<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5052387</id><updated>2012-01-23T17:55:35.442-08:00</updated><category term='triangles'/><category term='flash'/><category term='design'/><category term='math'/><category term='maps'/><category term='project'/><category term='grids'/><category term='review'/><category term='ideas'/><category term='programming'/><title type='text'>Blobs in Games</title><subtitle type='html'>I had been experimenting with simulation of environment (water, forests, etc.), people (civilians, military), economics (supply/demand, business), and transportation (trucks, railroads, warehousing) in games.  However I haven’t had the energy to work on a full game, so I mainly explore little things here and there.  On this blog I post my game-related thoughts, even if they aren&amp;#39;t related to the games I want to work on.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>99</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5052387.post-5164473057399323856</id><published>2012-01-23T17:38:00.001-08:00</published><updated>2012-01-23T17:55:35.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Kingdoms of Amalur game maps</title><content type='html'>&lt;p&gt;Last month I described the reasons I don&amp;#8217;t like &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/skyrim-maps/"&gt;the maps in Skyrim&lt;/a&gt;. Below are some maps from &lt;a href="http://www.rockpapershotgun.com/2011/10/11/hands-on-kingdoms-of-amalur-reckoning/"&gt;Kingdoms of Amalur: Reckoning&lt;/a&gt;, a game that&amp;#8217;s been compared to Skyrim.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the world map in the game:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/Sd3EFKYtfvOgwBji6oJUEdMTjNZETYmyPJy0liipFm0?feat=directlink"&gt;&lt;img src="https://lh3.googleusercontent.com/-iJnEgNPP47A/Tx3pIUtMQvI/AAAAAAAAGIA/hoU0pTP24GY/s800/World%252520map%252520close%252520up.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It shows where I am, the areas I&amp;#8217;ve discovered so far, my current destination, areas of the world along with their names, and ways to travel between areas/zones. The map uses light shading and subtle texturing to keep the main areas clear and readable. Non-walkable areas are darker and strongly shaded to distinguish them from the main areas.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a local area map in the game:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/OdzSQYYWdIhZHl5peDA559MTjNZETYmyPJy0liipFm0?feat=embedwebsite"&gt;&lt;img src="https://lh5.googleusercontent.com/-gqWhSOkD_1c/Tx3pISleQ2I/AAAAAAAAGIM/H_mm05SZgM8/s800/Area%252520map%2525201%252520close%252520up.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It shows where I am, portals, merchants, healers, NPCs (white circles), dungeons, roads (main and side), shrines (green circles), and things I&amp;#8217;ve spotted but not investigated yet (brown boxes). The investigation spots only show up if I&amp;#8217;ve leveled up an exploration skill. In the northwest an area is dark because I haven&amp;#8217;t explored it yet. Walkable areas are tan or gray, with subtle texturing. Non-walkable areas and unexplored areas are dark.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s another area:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/JjNjW3mmhSnPmO3z0mUG1dMTjNZETYmyPJy0liipFm0?feat=embedwebsite"&gt;&lt;img src="https://lh3.googleusercontent.com/-i1qOntDeIf4/Tx3pIDTt70I/AAAAAAAAGH8/giz_qWWet-c/s800/Area%252520map%2525202%252520close%252520up.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It shows larger and smaller roads, two bridges, a river, and monsters I&amp;#8217;ve spotted. The monsters only get placed on my map if I have leveled up an exploration skill. Several areas fade to black because I haven&amp;#8217;t explored them yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I love these maps!&lt;/strong&gt;  They are clean and easy to read. They show what&amp;#8217;s important. They omit irelevant details (clouds, rocks, trees, plants). They&amp;#8217;re updated as I explore and discover new things. They help me figure out where to go and how to get there.&lt;/p&gt;
&lt;p&gt;How well do these maps answer the questions from my &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/skyrim-maps/"&gt;post about Skyrim&amp;#8217;s maps&lt;/a&gt;?&lt;/p&gt;
&lt;table class="standard"&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Player question&lt;/th&gt;&lt;th&gt;Amalur&lt;/th&gt;&lt;th&gt;Skyrim&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Where have I been?&lt;/th&gt;&lt;td bgcolor="#ddffee"&gt;places, zones, roads&lt;/td&gt;&lt;td&gt;places only&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What areas have I missed?&lt;/th&gt;&lt;td&gt;area map only&lt;/td&gt;&lt;td&gt;area map only&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What have I done?&lt;/th&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Where can I find resources?&lt;/th&gt;&lt;td bgcolor="#ddffee"&gt;some *&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Where can I get some product/service?&lt;/th&gt;&lt;td bgcolor="#ddffee"&gt;yes&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What do I want to return to?&lt;/th&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Where have I been told to go?&lt;/th&gt;&lt;td&gt;one quest&lt;/td&gt;&lt;td bgcolor="#ddffee"&gt;all quests&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What are the main areas?&lt;/th&gt;&lt;td&gt;zones only&lt;/td&gt;&lt;td bgcolor="#ddffee"&gt;zones, lakes, rivers, towns&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What locations have I been told about?&lt;/th&gt;&lt;td&gt;(don&amp;#8217;t know)&lt;/td&gt;&lt;td bgcolor="#ddffee"&gt;places only&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;How do I get to a specific place?&lt;/th&gt;&lt;td bgcolor="#ddffee"&gt;yes&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;How long would it take me to get somewhere&lt;/th&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What dangers are along various paths?&lt;/th&gt;&lt;td bgcolor="#ddffee"&gt;in area map only *&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Where are events occurring?&lt;/th&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What has changed?&lt;/th&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;What did I miss?&lt;/th&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=3 align=center&gt; * requires leveling up an exploration skill&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;I only played the demo for a short time, so it&amp;#8217;s possible I&amp;#8217;ve missed
some aspects of the maps in Kingdoms of Amalur. I&amp;#8217;m finding the
maps to be much more useful than the ones in Skyrim.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5164473057399323856?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5164473057399323856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5164473057399323856' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5164473057399323856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5164473057399323856'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2012/01/kingdoms-of-amalur-game-maps.html' title='Kingdoms of Amalur game maps'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-iJnEgNPP47A/Tx3pIUtMQvI/AAAAAAAAGIA/hoU0pTP24GY/s72-c/World%252520map%252520close%252520up.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5547231155700969873</id><published>2012-01-22T18:16:00.001-08:00</published><updated>2012-01-22T18:16:30.716-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Tutorial: probability and damage rolls</title><content type='html'>&lt;p&gt;I&amp;#8217;ve been &lt;a href="http://simblob.blogspot.com/2007/07/interactive-illustrations.html"&gt;interested in interactive diagrams&lt;/a&gt; for a while now, and started playing making illustrations with HTML5. I&amp;#8217;ve written a &lt;a href="http://www.redblobgames.com/articles/probability/damage-rolls.html"&gt;&lt;strong&gt;tutorial on using randomness for damage rolls&lt;/strong&gt;&lt;/a&gt;. Implementation notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;#8217;m using Mike Bostock&amp;#8217;s &lt;a href="http://mbostock.github.com/d3/"&gt;D3.js&lt;/a&gt; + SVG for the diagrams.&lt;/li&gt;
&lt;li&gt;I&amp;#8217;m using Bret Victor&amp;#8217;s &lt;a href="http://worrydream.com/Tangle/"&gt;Tangle&lt;/a&gt; library for diagram parameters.&lt;/li&gt;
&lt;li&gt;You can drag the parameters around to change the diagrams. The idea is that you can edit the parameters in the sample code, and see the diagram update too.&lt;/li&gt;
&lt;li&gt;The draggable numbers from Tangle work on the iPad too.&lt;/li&gt;
&lt;li&gt;Most (all?) Android and Touchpad browsers don&amp;#8217;t support SVG. &lt;code&gt;:-(&lt;/code&gt; (Maybe I should&amp;#8217;ve used Canvas)&lt;/li&gt;
&lt;li&gt;Older versions of Internet Explorer don&amp;#8217;t support SVG. &lt;code&gt;:-(&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I designed the page to reformat itself for mobile browsers, narrow browsers, and wide browsers. I used CSS media queries for reformatting the text, but unfortunately had to use Javascript for redrawing the diagrams.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.redblobgames.com/"&gt;Red Blob Games&lt;/a&gt; is where I&amp;#8217;ll be placing my new tutorials and articles, instead of my Stanford alumni account.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At some point I&amp;#8217;d like to go back to my existing articles and update them with interactive diagrams. I&amp;#8217;m just not yet sure where they might be useful instead of gimmicky. I&amp;#8217;d also like to write a tutorial about random loot drops.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5547231155700969873?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5547231155700969873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5547231155700969873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5547231155700969873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5547231155700969873'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2012/01/tutorial-probability-and-damage-rolls.html' title='Tutorial: probability and damage rolls'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4463275466168470462</id><published>2011-12-07T12:14:00.000-08:00</published><updated>2011-12-07T22:20:22.054-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Skyrim and game maps</title><content type='html'>&lt;p&gt;
I've been playing Skyrim lately. A &lt;em&gt;lot&lt;/em&gt; of Skyrim: over 70 hours in 3 weeks. Naturally, I had some thoughts on the maps in the game.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/skyrim-maps/"&gt;Read the article on my main site&lt;/a&gt;. 
&lt;/p&gt;

&lt;p&gt;
Side note: I'm not really happy with my blog format. It's designed around updates, but many of my writings are more “reference” style articles that I'll update over time. With the polygon map posts, I experimented with formatting the content twice, once for the blog and once for the site. That led to fragmented discussions, and it was also a lot of extra work for me. For some posts I experimented by having a reference-style post only on the blog, but these didn't fit well into the main site. For this post I'm experimenting with the opposite — I'm keeping the content on the main site, but using the blog only as a pointer to it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4463275466168470462?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4463275466168470462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4463275466168470462' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4463275466168470462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4463275466168470462'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2011/12/skyrim-and-game-maps.html' title='Skyrim and game maps'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4669253496459190759</id><published>2011-10-17T21:13:00.000-07:00</published><updated>2011-10-17T22:23:56.496-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><title type='text'>Crafting graphs</title><content type='html'>&lt;p&gt;I&amp;#8217;ve only played a few games with crafting, but the basic approach seems to be that I collect some materials and then combine them into what I want to make. In some games the recipes are in the game; in others I have to find them on a wiki. Many games have multi-step crafting, where I can use a crafted item as a material to craft another item.&lt;/p&gt;

&lt;p&gt;In a game where I find crafting materials randomly (e.g. &lt;a href="http://www.dungeonsofdredmor.com/"&gt;Dungeons of Dredmore&lt;/a&gt;), the question I want to answer is &lt;em&gt;which of these items do I want to make with what I have, or do I want to wait?&lt;/em&gt;. For example, if I find a Gel in Terraria, this is what I can make, sometimes by combining Gel with something else:&lt;/p&gt;

&lt;p style="text-align:center"&gt;
&lt;img style="max-width:100%" src="http://theory.stanford.edu/~amitp/diagrams/crafting-graph/where-can-i-go.png" alt="Diagram of what I can craft given what I have" /&gt;
&lt;/p&gt;


&lt;p&gt;In a game where I can choose to find materials (e.g. &lt;a href="http://www.terraria.org/"&gt;Terraria&lt;/a&gt;) or buy materials (e.g. World of Warcraft), the question I want to answer is &lt;em&gt;what materials do I need to make what I want?&lt;/em&gt; For example, if I want a Hero&amp;#8217;s Hat in Terraria, this is what I need:&lt;/p&gt;

&lt;p&gt;
&lt;img style="max-width:100%" src="http://theory.stanford.edu/~amitp/diagrams/crafting-graph/what-do-i-need.png" alt="Diagram of what I need to craft something" /&gt;
&lt;/p&gt;


&lt;p&gt;Both of these are subsets of a crafting graph, which may be rather complex and difficult to show on the screen at once. This is an approximate graph for Minecraft crafting:&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://theory.stanford.edu/~amitp/diagrams/crafting-graph/crafting.png"&gt;&lt;img style="max-width:100%" src="http://theory.stanford.edu/~amitp/diagrams/crafting-graph/crafting-small.png" alt="Diagram of Minecraft crafting graph" /&gt;&lt;/a&gt;
&lt;/p&gt;


&lt;p&gt;I either want to look forwards from the materials I currently have or I want to look backwards from the items I want to make. Games typically give me a UI that only shows a single step forwards. They can&amp;#8217;t show the entire crafting graph because it&amp;#8217;s typically too complex.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d like better ways to interact with the crafting graph:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In games with a complex crafting graph, help me explore it in the game so I don&amp;#8217;t need to use a wiki to find the information.&lt;/li&gt;
&lt;li&gt;In games where I&amp;#8217;m discovering crafting recipes, help me track what I&amp;#8217;ve learned and what I&amp;#8217;m missing.&lt;/li&gt;
&lt;li&gt;In games where I&amp;#8217;m able to pick which materials to find, help me track goals like &amp;#8220;make Hero&amp;#8217;s Hat&amp;#8221; that translate into subgoals like &amp;#8220;find 9 seeds from the Jungle&amp;#8221;.&lt;/li&gt;
&lt;li&gt;In games where I&amp;#8217;m unable to pick which materials to find, consider adjusting the loot drop rates to favor materials that would be useful for the goals I&amp;#8217;ve set.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the good old days, RPGs didn&amp;#8217;t explicitly track the map or quests for you. Instead, you did it yourself, on paper. These days, RPGs have removed much of the mundane aspects of tracking things by automatically remembering things for you. There are nifty interfaces for maps, skill/tech trees, quests, subquests, lore, and so on. I&amp;#8217;d like to see that sort of thinking applied to crafting.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4669253496459190759?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4669253496459190759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4669253496459190759' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4669253496459190759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4669253496459190759'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2011/10/crafting-graphs.html' title='Crafting graphs'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-8662869628279773638</id><published>2010-09-06T15:19:00.000-07:00</published><updated>2011-08-31T08:02:33.033-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Polygon map generation, part 3</title><content type='html'>&lt;p&gt;In the previous blog posts (&lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html"&gt;part
1&lt;/a&gt; 
   and &lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-2.html"&gt;part
2&lt;/a&gt;),
   I described generating random polygonal maps with elevation, moisture,
   biomes, and rivers. For some games, those maps are
   sufficient. However, in other games I want to hide the polygon
   structure. In this blog post I'll describe how to render the polygons
   into a game map that doesn't look polygonal, and conclude with the
   demo and source code.
&lt;/p&gt; 

&lt;p&gt;
&lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;The &lt;strong&gt;full article&lt;/strong&gt; is here&lt;/a&gt;. There's also a &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2.swf"&gt;demo&lt;/a&gt; and &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/#source"&gt;source code&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;Noisy Edges&lt;/h3&gt; 
 
&lt;p&gt;Recall from earlier that there are &lt;em&gt;two&lt;/em&gt; graphs: one for Voronoi
   corners (&lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; in the diagram below) and edges (blue lines), and
   one for polycon centers (&lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;) and Delaunay edges (red
   lines) between them:
&lt;/p&gt; 
&lt;img width="306" height="250" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/edge-duality.png" alt="Diagram showing duality between edges in two graphs" /&gt; 
 
&lt;p&gt;I wanted to add some “noise” to the the straight lines. I tried making
   them move randomly, but sometimes lines would cross, and I realized I
   needed to constrain them so that they would never cross each other.
   The second thing I wanted was to make sure that the lines had as much
   space to wander as possible.
&lt;/p&gt; 
&lt;p&gt;I realized that points &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, and &lt;code&gt;2&lt;/code&gt; form a quadrilateral, and
   I could constrain the wanderings of the line segment to that quadrilateral:
&lt;/p&gt; 
&lt;img width="400" height="327" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/edge-noisiness.png" alt="Diagram showing quadrilateral where noisy edges can be drawn" /&gt; 
 
&lt;p&gt;I further divided the quadrilateral into four quadrilaterals. Two were
   usable for the red (Delaunay) edge and two for the blue (Voronoi)
   edge. As long as the lines stayed within their allocated space and met
   in the center, they'd never cross each other. That takes care of
   constraining them.
&lt;/p&gt; 
&lt;p&gt;The entire map can be divided up into these quadrilateral regions,
   with no space left over:
&lt;/p&gt; 
&lt;img width="400" height="400" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/quad-markings.png" alt="Map area divided into quadrilaterals" /&gt; 
 
&lt;p&gt;That ensures that the noisy lines aren't constrained any more than
   necessary. (I wonder if these quadrilaterals would be useful for game
   mechanics.)
&lt;/p&gt; 
&lt;p&gt;I can use any noisy line algorithm that fits within these
   constraints. I decided to subdivide the quadrilaterals recursively and
   stitch line segments together within the small quadrilaterals into a
   complete edge. The result is here:
&lt;/p&gt; 
&lt;img width="400" height="400" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/biomes-noisy.png" alt="Map with noisy biome boundaries" /&gt; 
 
&lt;p&gt;The noisiness is tunable, and I have examples at &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/biomes-noisy-7.png"&gt;segment size
7&lt;/a&gt;, &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/biomes-noisy-4.png"&gt;segment size 4&lt;/a&gt;, and
   &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/biomes-noisy-1.png"&gt;segment size 1&lt;/a&gt;.  In the map demo I use segment
   size 1 for rivers and coastlines, 3 where biomes meet, and 10
   elsewhere.
&lt;/p&gt; 
&lt;h3&gt;More noise&lt;/h3&gt; 
 
&lt;p&gt;I'm generally a fan of &lt;a href="http://simblob.blogspot.com/2009/06/noise-in-game-art.html"&gt;noise in game
art&lt;/a&gt;, and
   wanted to add a little bit of noise to these maps as well. In a real
   game map the noise might reflect vegetation or small variations in
   terrain. In the demo I just filled the screen with a random noise
   texture, and smoothed the colors between adjacent polygons:
&lt;/p&gt; 
&lt;img width="400" height="400" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal.png" alt="Map with noisy boundaries and noise texture" /&gt; 

&lt;p&gt;However, with a bit more random noise, we can generate this (described in the &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;full article&lt;/a&gt;):&lt;/p&gt;
&lt;img width="400" height="400" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal-distorted.png" alt="Map with noisier boundaries" /&gt; 

&lt;p&gt;Here's a rendering with 16,000 polygons, noisy edges, a noise texture
   overlay, and simple lighting:
&lt;/p&gt; 
&lt;div class="hmedia"&gt;&lt;img class="photo" width="600" height="600" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal-16000-shaded.png" alt="Shaded map with 16,000 polygons" /&gt; &lt;/div&gt;
 
&lt;h3&gt;Demo&lt;/h3&gt; 
 
&lt;p&gt;I wrote a Flash demo to explore the generated maps:
&lt;/p&gt; 
&lt;img width="600" height="400" src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2-ui.png" alt="Screenshot of mapgen2 demo" /&gt; 
 
&lt;p&gt;The simplest way to explore the maps is to click Random and the
   various View options.
&lt;/p&gt; 
&lt;p&gt;&lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2.swf"&gt;Try the demo&lt;/a&gt;!
&lt;/p&gt; 
&lt;p&gt;In a shape number like &lt;code&gt;85882-3&lt;/code&gt;, 85882 chooses the overall island
   shape and 3 is the random number seed for the details (random points,
   noisy edges, rivers, lava).  You can type in a shape number and press
   Return to generate that map.  The demo also shows some unfinished
   features that may be useful for some games: lava, roads, and
   watersheds.
&lt;/p&gt; 
&lt;h3&gt;Source&lt;/h3&gt; 
 
&lt;p&gt;I've placed the Actionscript source under the MIT license; it's
   &lt;a href="http://github.com/amitp/mapgen2"&gt;available on github&lt;/a&gt;. There's an
   &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;overview
page&lt;/a&gt; 
   describing what's in these blog posts, along with notes about the
   code. I don't expect that the code will be immediately useful to
   anyone, but it might be a useful starting point if you'd like to use
   these techniques for making your own game maps.  The diagrams are
   built with 300 polygons, the demo uses 2000, and the code can go much
   higher, although I've not tried above 16,000.
&lt;/p&gt; 
&lt;p&gt;If you find the ideas or code useful, I'd love to hear about it!
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: [2010-09-22] I added a noisier rendering, which is described in the full article.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-8662869628279773638?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/8662869628279773638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=8662869628279773638' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8662869628279773638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8662869628279773638'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/09/polygon-map-generation-part-3.html' title='Polygon map generation, part 3'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-8436125850704740220</id><published>2010-09-05T14:29:00.000-07:00</published><updated>2011-08-31T08:03:01.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Polygon map generation, part 2</title><content type='html'>&lt;p&gt;In the &lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html"&gt;previous blog post&lt;/a&gt; 
   I described creating polygon island maps. Given random points, Voronoi
   diagrams with Lloyd relaxation produce a nice set of polygons. The
   polygons, their edges, and their corners can be represented as two
   related graphs. Given a random shape, those polygons can be marked as
   land, ocean, or lake. In this blog post I'll describe how to add
   elevation, rivers, moisture, and biomes to make the maps interesting.
&lt;/p&gt; 

&lt;p&gt;
&lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;The &lt;strong&gt;full article&lt;/strong&gt; is here&lt;/a&gt;. There's also a &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2.swf"&gt;demo&lt;/a&gt; and &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/#source"&gt;source code&lt;/a&gt;.
&lt;/p&gt;


&lt;h3&gt;Elevation&lt;/h3&gt; 
 
&lt;p&gt;The most realistic approach would have been to define elevation first,
   and then define the coastline to be where the elevation reaches sea
   level. Instead, I'm starting with the goal, which is a good coastline,
   and working backwards from there.  I set elevation to be the
   &lt;strong&gt;distance from the coast&lt;/strong&gt;. I originally tried elevations at polygon
   centers but setting elevations at corners worked out
   better. Corner-to-corner edges can serve as ridges and valleys. After
   calculating the elevation of corners, the polygon elevation is the
   average of the elevation at the corners.
&lt;/p&gt; 
&lt;p&gt;Water polygons don't count towards the distance. This is both because
   I expect lakes to be flat instead of sloped, and because this tends to
   build valleys around lakes, which helps guide rivers towards lakes.
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/elevations.png" alt="Elevation map" /&gt; 
 
&lt;p&gt;One problem with the simple definition is that some islands have too
   many mountains and others have too few.  To fix this, I redistribute
   the elevations to match a desired distribution, which has more low
   elevation land (coastline) than high elevation land (mountains).
&lt;/p&gt; 
&lt;p&gt;Elevations always increase from the coast to the mountains. That means
   that for any location, going downhill will eventually lead to the
   ocean. This diagram shows the steepest downhill direction from every
   corner:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/downslopes.png" alt="Elevation map with arrows pointing downhill" /&gt; 
 
&lt;p&gt;By following the downhill arrows from any location, we eventually
   reach the ocean. This will be useful for rivers but may also be useful
   for calculating watersheds and other features.
&lt;/p&gt; 
&lt;p&gt;I had two main goals for elevation:
&lt;/p&gt; 
&lt;ol&gt; 
 &lt;li&gt; 
     &lt;strong&gt;Biome&lt;/strong&gt; types: high elevations get snow, rock, tundra; medium elevations get shrubs, deserts, forests, and grassland; low elevations get rain forests, grassland, and beaches.
 &lt;/li&gt; 
 
 &lt;li&gt; 
     &lt;strong&gt;Rivers&lt;/strong&gt; flow from high elevations down to the coast. Having elevations that always increase away from the coast means that there's no local minima that complicate river generation.
 &lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;In addition, games may define their own use of elevation data. For
   example, &lt;a href="http://www.realmofthemadgod.com/"&gt;Realm of the Mad God&lt;/a&gt; uses
   elevation to distribute monsters.
&lt;/p&gt; 
&lt;h3&gt;Rivers&lt;/h3&gt; 
 
&lt;p&gt;Rivers and lakes are the two fresh water features I wanted.  The most
   realistic approach would be to define moisture with wind, clouds,
   humidity, and rainfall, and then define the rivers and lakes based on
   where it rains. Instead, I'm starting with the goal, which is good
   rivers, and working backwards from there. 
&lt;/p&gt; 
&lt;p&gt;The island shape determines which areas are water and which are
   land. Lakes are water polygons that aren't oceans. 
&lt;/p&gt; 
&lt;p&gt;Rivers use the downhill directions shown earlier. I choose random
   corner locations in the mountains, and then follow a path down to the
   ocean.  The rivers flow from corner to
   corner:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/river.png" alt="Elevation map with one river" /&gt; 
 
&lt;p&gt;I tried both polygon centers and corners, but found that the corner
   graph made for much nicer looking rivers. Also, by keeping lakes flat,
   elevation tends to be lower near lakes, so rivers naturally flow into
   and out of lakes. Multiple rivers can share the lower portion of their
   path, but once they join, they never diverge, so tributary formation
   comes for free. It's simple and seems to work pretty well.
&lt;/p&gt; 
&lt;h3&gt;Moisture&lt;/h3&gt; 
 
&lt;p&gt;Since I'm working backwards, I don't need moisture to form
   rivers. However, moisture would be useful for defining &lt;strong&gt;biomes&lt;/strong&gt; 
   (deserts, swamps, forests, etc.). Since rivers and lakes should form in areas
   with high moisture, I defined moisture based on &lt;strong&gt;distance from fresh
water&lt;/strong&gt;:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/moisture.png" alt="Moisture map" /&gt; 
 
&lt;p&gt;As with elevation, I redistribute moisture to match a desired
   distribution. In this case, I want roughly equal numbers of dry and
   wet regions.  In this map generator, moisture is only used for
   biomes. However, games may find other uses for the moisture data.  For
   example, &lt;a href="http://www.realmofthemadgod.com/"&gt;Realm of the Mad God&lt;/a&gt; uses
   moisture and elevation to distribute vegetation.
&lt;/p&gt; 
&lt;h3&gt;Biomes&lt;/h3&gt; 
 
&lt;p&gt;Together, elevation and moisture provide a good amount of variety to
   define biome types. I use elevation as a proxy for temperature. Biomes
   first depend on whether it's water or land:
&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt; 
     &lt;strong&gt;Ocean&lt;/strong&gt; is any water polygon connected to the map border
 &lt;/li&gt; 
 
 &lt;li&gt; 
     &lt;strong&gt;Lake&lt;/strong&gt; is any water polygon not connected to the map border
&lt;ul style="margin-top:0;margin-bottom:0"&gt; 
 &lt;li&gt; 
     &lt;strong&gt;Ice lake&lt;/strong&gt; if the lake is at high elevation (low temperature)
 &lt;/li&gt; 
 
 &lt;li&gt; 
     &lt;strong&gt;Marsh&lt;/strong&gt; if it's at low elevation
 &lt;/li&gt; 
&lt;/ul&gt; 
 
 &lt;/li&gt; 
 
 &lt;li&gt; 
     &lt;strong&gt;Beach&lt;/strong&gt; is any land polygon next to an ocean
 &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;For all land polygons, I started with the &lt;a href="http://www.marietta.edu/~biol/biomes/biome_main.htm"&gt;Whittaker
diagram&lt;/a&gt; and
   adapted it to my needs:
&lt;/p&gt; 
&lt;table class=standard width="100%" style="font-size:x-small"&gt; 
  &lt;thead&gt; 
    &lt;tr&gt;&lt;th width="10%" rowspan=2&gt;Elevation&lt;/th&gt;&lt;th colspan=6&gt;Moisture&lt;/th&gt;&lt;/tr&gt; 
    &lt;tr&gt;&lt;th width="15%"&gt;Wet&lt;/th&gt;&lt;th width="15%"&gt;&lt;/th&gt;&lt;th width="15%"&gt;&lt;/th&gt;&lt;th width="15%"&gt;&lt;/th&gt;&lt;th width="15%"&gt;&lt;/th&gt;&lt;th width="15%"&gt;Dry&lt;/th&gt;&lt;/tr&gt; 
  &lt;/thead&gt; 
  &lt;tbody style="text-align:center"&gt; 
    &lt;tr style="height:3em"&gt;&lt;th&gt;High&lt;/th&gt;&lt;td style="background:#f8f8f8" colspan=3&gt;Snow&lt;/td&gt;&lt;td style="background:#ddddbb"&gt;Tundra&lt;/td&gt;&lt;td style="background:#bbbbbb"&gt;Bare rock&lt;/td&gt;&lt;td style="background:#999999"&gt;Scorched&lt;/td&gt;&lt;/tr&gt; 
    &lt;tr style="height:3em"&gt;&lt;th&gt;Medium-high&lt;/th&gt;&lt;td style="background:#ccd4bb" colspan=2&gt;Taiga&lt;/td&gt;&lt;td style="background:#c4ccbb" colspan=2&gt;Shrubland&lt;/td&gt;&lt;td style="background:#e4e8ca" colspan=2&gt;Temperate desert&lt;/td&gt;&lt;/tr&gt; 
    &lt;tr style="height:3em"&gt;&lt;th&gt;Medium-low&lt;/th&gt;&lt;td style="background:#a4c4a8"&gt;Temperate rain forest&lt;/td&gt;&lt;td style="background:#b4c9a9" colspan=2&gt;Temperate deciduous forest&lt;/td&gt;&lt;td style="background:#c4d4aa" colspan=2&gt;Grassland&lt;/td&gt;&lt;td style="background:#e4e8ca"&gt;Temperate desert&lt;/td&gt;&lt;/tr&gt; 
    &lt;tr style="height:3em"&gt;&lt;th&gt;Low&lt;/th&gt;&lt;td style="background:#9cbba9" colspan=2&gt;Tropical rain forest&lt;/td&gt;&lt;td style="background:#a9cca4" colspan=2&gt;Tropical seasonal forest&lt;/td&gt;&lt;td style="background:#c4d4aa"&gt;Grassland&lt;/td&gt;&lt;td style="background:#e9ddc7"&gt;Subtropical desert&lt;/td&gt;&lt;/tr&gt; 
  &lt;/tbody&gt; 
&lt;/table&gt; 
 
&lt;p&gt;Here's the result:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/biomes.png" alt="Biome map" /&gt; 
 
&lt;p&gt;These biomes look good in the map generation demo, but each game will
   have its own needs. &lt;a href="http://www.realmofthemadgod.com/"&gt;Realm of the Mad
God&lt;/a&gt; for example ignores these
   biomes and uses its own (based on elevation and moisture).
&lt;/p&gt; 
&lt;p&gt;In the &lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-3.html"&gt;last blog post&lt;/a&gt; I'll describe how I get from this biome map to
   maps like this: (or even &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal-8000.png"&gt;this&lt;/a&gt;!)
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal-distorted.png" alt="Goal of the map generation" /&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt;: [2010-09-22] I replaced the last diagram on this page with what I originally wanted but didn't finish in time for the blog post. At the time of posting, I used &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal.png"&gt;this image&lt;/a&gt; instead.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-8436125850704740220?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/8436125850704740220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=8436125850704740220' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8436125850704740220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8436125850704740220'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/09/polygon-map-generation-part-2.html' title='Polygon map generation, part 2'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7532940127463060178</id><published>2010-09-04T08:37:00.000-07:00</published><updated>2011-08-31T08:03:14.532-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Polygon map generation, part 1</title><content type='html'>&lt;p&gt;I wanted to generate interesting game maps that &lt;a href="http://simblob.blogspot.com/2010/06/teleological-vs-ontogenetic-map.html"&gt;weren't constrained to
   be realistic&lt;/a&gt;, and I wanted to try some techniques I hadn't tried
   before. I usually make tile maps but this time I decided to make
   polygonal maps. Instead of 1,000,000 tiles, what could I do with 1,000
   polygons? I think the distinct player-recognizable areas might be
   useful for gameplay: locations of towns, places to quest, territory to
   conquer or settle, pathfinding waypoints, difficulty zones, etc.
&lt;/p&gt; 
&lt;p&gt;There were three main things I wanted: good coastlines, mountains and
   rivers. For the coastline, I wanted to make island/continent maps that
   are surrounded by ocean, so that I don't have to deal with people
   walking to the edge of the map. For the mountains, I started with
   something simple: mountains are whatever's farthest from the
   coastline. For the rivers, I started with something simple: draw
   rivers from the coast to the mountains.
&lt;/p&gt; 

&lt;p&gt;
&lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;The &lt;strong&gt;full article&lt;/strong&gt; is here&lt;/a&gt;. There's also a &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/mapgen2.swf"&gt;demo&lt;/a&gt; and &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/#source"&gt;source code&lt;/a&gt;.
&lt;/p&gt;


&lt;h3&gt;Polygons&lt;/h3&gt; 
 
&lt;p&gt;The first step is to generate some polygons. I picked random points
   and generated &lt;a href="http://en.wikipedia.org/wiki/Voronoi_diagram"&gt;Voronoi
polygons&lt;/a&gt;, which are
   used for &lt;a href="http://www.voronoi.com/wiki/index.php?title=Voronoi_Applications"&gt;lots of
things&lt;/a&gt;,
   including maps. Here's an example of random dots (red) and the
   polygons that result:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-polygons.png" alt="Voronoi diagram" /&gt; 
 
&lt;p&gt;The first problem is that polygon shapes and sizes are a bit irregular. Random numbers are
   more “clumpy” than what people expect. What I really want is
   semi-random “blue noise”, not random points. I approximate that by
   using &lt;a href="http://en.wikipedia.org/wiki/Lloyd's_algorithm"&gt;Lloyd
relaxation&lt;/a&gt;, which is
   a fairly simple tweak to the random point locations to make them more
   evenly distributed. Here's the result after running Lloyd relaxation twice:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-2-lloyd.png" alt="Voronoi diagram with Lloyd relaxation run twice" /&gt; 
 
&lt;p&gt;Compare it to running &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-1-lloyd.png"&gt;once&lt;/a&gt; or &lt;a 
href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-50-lloyd.png"&gt;fifty times&lt;/a&gt;. The more iterations, the
   more regular the polygons get.  Running it twice gives me good results
   but every game will vary in its needs.
&lt;/p&gt; 

&lt;p&gt;
[2010-09-22] The second problem with the polygons is that some edges are very short. For games where boundaries between polygons matters, having short edges is a problem. We can adjust the edge lengths by moving corners, but we lose the Voronoi properties. Since I'm using Voronoi only to generate polygons, and do not need to preserve the Voronoi properties, I move the corners to the average of the polygon centers they touch. Note: I added this code after the initial blog post, and did not update diagrams to show this step.
&lt;/p&gt;

&lt;h3&gt;Map Representation&lt;/h3&gt; 
 
&lt;p&gt;I'm representing the map as two related
   &lt;a href="http://en.wikipedia.org/wiki/Graph_theory"&gt;graphs&lt;/a&gt;: nodes and
   edges. The first graph has nodes for each polygon and edges between
   adjacent polygons. It represents the &lt;a href="http://en.wikipedia.org/wiki/Delaunay_triangulation"&gt;Delaunay
triangulation&lt;/a&gt;,
   which is useful for anything involving adjacency (such as
   pathfinding). The second graph has nodes for each polygon &lt;em&gt;corner&lt;/em&gt; and
   edges between corners. It contains the shapes of the Voronoi
   polygons. It's useful for anything involving the shapes (such as
   rendering borders).
&lt;/p&gt; 
&lt;p&gt;The two graphs are related. Every triangle in the Delaunay
   triangulation corresponds to a polygon corner in the Voronoi
   diagram. Every polygon in the Voronoi diagram corresponds to a corner
   of a Delaunay triangle. Every edge in the Delaunay graph corresponds
   to an edge in the Voronoi graph. You can see this in the following
   diagram:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/edge-duality.png" alt="Diagram showing how Voronoi and Delaunay are related" /&gt; 
 
&lt;p&gt;Polygon &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are adjacent to each other, so there is a (red) edge
   between &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; in the adjacency graph. For them to be adjacent there
   must be a polygon edge between them. The (blue) polygon edge connects
   corners &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; in the Voronoi shape graph.  &lt;em&gt;Every&lt;/em&gt; edge in the
   adjacency graph corresponds to exactly one edge in the shape graph.
&lt;/p&gt; 
&lt;p&gt;In the Delaunay triangulation, triangle &lt;code&gt;A&lt;/code&gt;-&lt;code&gt;B&lt;/code&gt;-&lt;code&gt;C&lt;/code&gt; connects the three
   polygons, and can be represented by corner &lt;code&gt;2&lt;/code&gt;.  Thus, corners in the
   Delaunay triangulation are polygons in the Voronoi diagram, and vice
   versa.  Here's a larger example showing the relationship, with Voronoi
   polygon centers in red and corners in blue, and the Voronoi edges in
   white and the Delaunay triangulation in black:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-and-delaunay.png" alt="Example Voronoi diagram with Delaunay overlay" /&gt; 
 
&lt;p&gt;This duality means that I can represent the two graphs together.
   Edges are the key.  Each edge in a normal graph points to two
   nodes. Instead of representing two edges in the two graph separately,
   I made edges point to &lt;em&gt;four&lt;/em&gt; nodes: two polygon centers and two
   corners. It turns out to be quite useful to connect the two graphs
   together.
&lt;/p&gt; 
&lt;p&gt;With the combined representation, I can now use the Relationships
   Between Grid Parts sections of my &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/#relationships"&gt;article on
grids&lt;/a&gt;. They're
   not grids so I'm not assigning grid coordinates, but many of the
   algorithms that work on grids also work here, and the algorithms that
   work on graphs also work here (on either of the two graphs).
&lt;/p&gt; 
&lt;h3&gt;Islands&lt;/h3&gt; 
 
&lt;p&gt;The second step is to draw the coastline. I used a simple function to
   divide the world into land and water. There are many different ways to
   do this. You can even draw your own shapes, e.g., a skull island. The
   map generator works with any division of points, but it forces the
   outer layer of polygons to be ocean. Here's an example that divides
   the world into land and water:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-land-water.png" alt="Polygon map with land and water chosen" /&gt; 
 
&lt;p&gt;A simple flood fill starting from the border of the map can determine
   which water areas are oceans (connected to the border) and lakes
   (surrounded by land):
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-land-ocean-lake.png" alt="Polygon map divided into land, ocean, and lake" /&gt; 
 
&lt;p&gt;In the next two blog posts (&lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-2.html"&gt;part 2&lt;/a&gt;, &lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-3.html"&gt;part 3&lt;/a&gt;) I'll describe how I add elevation data to
   build mountains and valleys, add moisture data for lakes and
   rivers, render the map so that it doesn't look polygonal, and conclude with the demo and source code. Together, elevation and moisture produce a good range of
   terrain and map features. The goal is to produce maps like this:
&lt;/p&gt; 
&lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal-distorted.png" alt="Goal of the map generation" /&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt;: [2010-09-22] Since the original blog post, I added a corner adjustment step to lengthen short edges. Just as Lloyd relaxation improves the polygon sizes, I needed to adjust the edge lengths. The adjustment does not preserve Voronoi properties, but I'm not using those properties so it worked out. I didn't update diagrams to reflect this change. I also improved map rendering and replaced the last diagram on this page. I originally wanted to have a rendering that didn't show the polygons at all, but couldn't get it to work in time, so at the time of the blog post I used &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/voronoi-map-goal.png"&gt;this rendering&lt;/a&gt; instead. The rendering technique is described in the &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/"&gt;full article&lt;/a&gt; but not in the blog posts.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7532940127463060178?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7532940127463060178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7532940127463060178' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7532940127463060178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7532940127463060178'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html' title='Polygon map generation, part 1'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-706780387597400711</id><published>2010-08-20T16:11:00.000-07:00</published><updated>2010-09-04T13:54:21.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><title type='text'>Map rendering: cutting corners</title><content type='html'>&lt;p&gt;
I was drawing tile maps in Flash and found a cheap trick that improved the appearance of the maps, so I thought I'd share. Here's how I had been drawing the tile map:
&lt;/p&gt;
&lt;p style="text-align:center"&gt;
&lt;a href="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLF8X-HI/AAAAAAAADxQ/-13QztwZo7w/s1600/Vertex+displacement+goal+is+to+address+sharp+corners.png"&gt;&lt;img height="320" src="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLF8X-HI/AAAAAAAADxQ/-13QztwZo7w/s320/Vertex+displacement+goal+is+to+address+sharp+corners.png" width="318" alt="Normal rendering of a tile map" style="max-width:90%" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
In a bitmap-based graphics engine, you can smooth the edges of the tiles either by adding transition tiles (see &lt;a href="http://playtechs.blogspot.com/2007/04/tileset-design-tip.html"&gt;this article&lt;/a&gt; or &lt;a href="http://www.lostgarden.com/2006/02/250-free-handdrawn-textures.html"&gt;this article&lt;/a&gt; or &lt;a href="http://www.gamedev.net/reference/articles/article934.asp"&gt;this article&lt;/a&gt;) or by using a blending mask between adjacent tiles.
&lt;/p&gt;

&lt;p&gt;
Flash, OpenGL, and DirectX are vector-based engines. The bitmap techniques still work, but there are new possibilities available. I'm drawing each square tile by filling a square polygon with a bitmap texture. The engine doesn't care that it's square; it works on any polygon. I'm taking advantage of this with what I call “&lt;b&gt;vertex displacement&lt;/b&gt;”:
&lt;/p&gt;

&lt;p style="text-align:center"&gt;
&lt;a href="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLF0k77I/AAAAAAAADxU/r7fs2fkRvJo/s1600/Vertex+displacement+with+smooth+corners.png" style="max-width:90%"&gt;&lt;img height="319" src="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLF0k77I/AAAAAAAADxU/r7fs2fkRvJo/s320/Vertex+displacement+with+smooth+corners.png" alt="Tile map with corners cut by displacing vertices" width="320" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I look at the four tiles touching each vertex. If three of them are the same and the fourth is different, I&amp;nbsp;&lt;b&gt;move the vertex&lt;/b&gt;&amp;nbsp;to expand the area of the three common tiles and shrink the area of the uncommon one. It's easier to see the effect with the polygon borders:
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a href="http://3.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLfgJU3I/AAAAAAAADxc/RO-KwrQhqps/s1600/Vertex+displacement+visible+on+grid.png"&gt;&lt;img height="320" src="http://3.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLfgJU3I/AAAAAAAADxc/RO-KwrQhqps/s320/Vertex+displacement+visible+on+grid.png" alt="Grid showing how vertices are displaced to cut corners" width="320" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
It turns out there are other fun things you can do with this trick. For example, a little bit of random noise on each vertex makes for a map that looks a little more hand drawn:
&lt;/p&gt;

&lt;p style="text-align: center"&gt;
&lt;a href="http://2.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLA5GkwI/AAAAAAAADxY/sEpTSvQutIQ/s1600/Vertex+displacement+noise.png"&gt;&lt;img height="257" src="http://2.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLA5GkwI/AAAAAAAADxY/sEpTSvQutIQ/s320/Vertex+displacement+noise.png" width="320" alt="Grid showing how vertices can be displaced randomly" style="max-width:90%"/&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I've also used it to animate the boundary between the ocean and the beach. I added vertex displacement to my &lt;a href="http://simblob.blogspot.com/2010/01/simple-map-generation.html"&gt;simple map generator&lt;/a&gt;; see &lt;a href="http://theory.stanford.edu/~amitp/game-programming/mapgen-realm-of-the-mad-god/mapgen-oryx-smooth.swf"&gt;the demo&lt;/a&gt; (Flash). Try changing the corner setting to adjust how much the corners get moved when three tiles are the same, and the random setting to adjust how much vertices get randomly moved. I have a &lt;a href="http://theory.stanford.edu/~amitp/game-programming/mapgen-realm-of-the-mad-god/mapgen-shoreline-rotated-tiles.swf"&gt;separate demo&lt;/a&gt; (also Flash) to show the animated coastline.
&lt;/p&gt;

&lt;p&gt;
The technique has its limitations. Terrain boundaries that don't fall on a 45° angle look wavy (see &lt;a href="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLUBcJbI/AAAAAAAADxg/5RwHkH-QadU/s1600/Vertex+displacement+does+not+handle+all+straight+lines.png"&gt;example&lt;/a&gt;). Some terrain types shouldn't meet in this way. And the biggest limitation is that it only applies when the terrain texture has no major features (such as trees, rocks, etc.). But it's a cheap enough trick that it's worth keeping in my toolbox.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-706780387597400711?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/706780387597400711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=706780387597400711' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/706780387597400711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/706780387597400711'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/08/map-rendering-cutting-corners.html' title='Map rendering: cutting corners'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_kV9ZnGnZL7M/TG8CLF8X-HI/AAAAAAAADxQ/-13QztwZo7w/s72-c/Vertex+displacement+goal+is+to+address+sharp+corners.png' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-381081183972999119</id><published>2010-06-13T09:06:00.000-07:00</published><updated>2011-04-03T22:33:09.134-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Teleological vs. ontogenetic map generation</title><content type='html'>&lt;p&gt;
&lt;strong&gt;Edit:&lt;/strong&gt; &lt;small&gt;The feedback from comments is that the names “teleological” and “ontogenetic” aren't good fits. I agree. There's an interpretation in which the terms work but there are also other ways to interpret them where it doesn't make sense. I had gotten the terms from the procedural content wiki, but in the future I'll avoid using these terms. I've changed the blog text to use “bottom up” and “top down”. Thanks for the feedback.&lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
Long ago, I spent years working on the terrain generation for a &lt;a href="http://www-cs-students.stanford.edu/~amitp/games.html"&gt;game I worked on&lt;/a&gt;. I used earthquake faults, volcanoes, soil erosion, lava, river erosion, sediment deposition, water flow, weather simulation, vegetation (affected soil, which affected erosion), forest fires, floods, continental uplift, and other physical processes. This is the &lt;s&gt;teleological approach&lt;/s&gt; &lt;b&gt;&lt;a href="http://pcg.wikidot.com/pcg-algorithm:teleological-vs-ontogenetic"&gt;bottom up approach&lt;/a&gt;&lt;/b&gt;&amp;nbsp;to making maps.
&lt;/p&gt;
&lt;p&gt;
To make good maps, I'd change parameters and run it to see if the maps looked good. I'd go back and change parameters again and again. Ideally I'd write a search/evolutionary algorithm that explored the parameter space. To do that I need to write code to determine whether a map will look to my eye, and I never did figure that out. I knew it when I saw it.
&lt;/p&gt;
&lt;p&gt;
The other approach to map making is &lt;s&gt;ontogenetic&lt;/s&gt; &lt;b&gt;top down&lt;/b&gt;. Start with the structure you want to see, and make algorithms produce that directly and fill in the details. This is what I did with last year's &lt;a href="http://simblob.blogspot.com/2010/01/simple-map-generation.html"&gt;simple map generation&lt;/a&gt; project. I had seen Perlin Noise, and thought, hm, that looks vaguely like a map — let's see how much work it takes to turn it into a map. Not much, it turns out!
&lt;/p&gt;
&lt;p&gt;
For the past month I've been working on a new map generation project. I wanted island/continent maps with rivers, and Perlin Noise wasn't a good fit for that. I tried making random mountains come out of the ocean, and then using water flow algorithms to carve out rivers. I've been tweaking and testing, tweaking and testing, tweaking and testing, and finally realized that I'm back to using bottom up algorithms. It's incredibly addictive. It &lt;i&gt;feels&lt;/i&gt;&amp;nbsp;right: erosion, mountains, gravity, and all the other “realistic” things that form terrain.
&lt;/p&gt;
&lt;p style="text-align: center"&gt;
&lt;a style="margin:1em" href="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TBT_17VrZXI/AAAAAAAADtY/FUBe6I-Uw_c/s1600/mapgen2-output.png"&gt; &lt;img alt="Example island produced by map generator" style="max-width:40%" src="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TBT_17VrZXI/AAAAAAAADtY/FUBe6I-Uw_c/s320/mapgen2-output.png" /&gt;&lt;/a&gt;
&lt;a style="margin:1em" href="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TBT_24ViGFI/AAAAAAAADtc/_ArWb1_HPp0/s1600/mapgen2-water.png" &gt;&lt;img alt="Example island's drainage vectors" style="max-width:40%" src="http://1.bp.blogspot.com/_kV9ZnGnZL7M/TBT_24ViGFI/AAAAAAAADtc/_ArWb1_HPp0/s320/mapgen2-water.png"  /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The trouble is that I really don't need all of that. I'm working on 2D Flash games, and I don't need &lt;i&gt;terrain&lt;/i&gt;; I need &lt;i&gt;maps&lt;/i&gt;. It doesn't need to be completely realistic. It just has to be interesting. So I'm stepping back a bit and switching back to the top-down approach. I'm drawing some maps that I like, and then I'll find algorithms that generate maps like those, instead of modeling physical processes that produce realistic terrain. I think this will lead to better maps with less work.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; [2010-09-04] See my &lt;a href="http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html"&gt;newer blog post&lt;/a&gt; to see the beginning of the new map generation project.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-381081183972999119?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/381081183972999119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=381081183972999119' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/381081183972999119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/381081183972999119'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/06/teleological-vs-ontogenetic-map.html' title='Teleological vs. ontogenetic map generation'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_kV9ZnGnZL7M/TBT_17VrZXI/AAAAAAAADtY/FUBe6I-Uw_c/s72-c/mapgen2-output.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3317008631071716031</id><published>2010-04-08T14:46:00.001-07:00</published><updated>2010-06-13T07:33:24.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Varying game difficulty</title><content type='html'>&lt;p&gt;
  Contrast is commonly used for visuals and sometimes for music but you can also use it for game difficulty. The usual pattern in nature is slow rises and sharp falls.
&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The stock market tends to slowly go up and occasionally drop dramatically.&lt;/li&gt;
  &lt;li&gt;When you build a sand castle on the beach, you slowly make it larger, and then suddenly a wave destroys it all.&lt;/li&gt;
  &lt;li&gt;Forests grow slowly, and once in a while a fire will wipe out large sections of forest.&lt;/li&gt;
  &lt;li&gt;Stress slowly builds up in rock faults, and then an earthquake will suddenly release a large amount of stress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
  In games we see this same pattern. Think of how many games you've seen that start off slow, build up, and then have a “boss” fight, followed by the relative calm of the next area. The difficulty or excitement might look a lot like a stock market plot.
&lt;/p&gt;

&lt;p&gt;
  One major difference between games and the patterns in nature is that you can't always predict the falls in nature. I've seen some games where a boss is unexpectedly followed by another boss, but usually you roughly know what's going to happen after a boss fight. In games where encounters are dynamically generated, it might be interesting for the encounters to follow a pattern like those seen in nature. More randomness with slow increases and sudden drops could make games more exciting.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3317008631071716031?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3317008631071716031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3317008631071716031' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3317008631071716031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3317008631071716031'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/04/varying-game-difficulty.html' title='Varying game difficulty'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7807899302486062319</id><published>2010-02-28T17:14:00.000-08:00</published><updated>2010-09-04T13:59:25.863-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Retro art: breaking the rules</title><content type='html'>&lt;p&gt;When you play a game with retro graphics, there are some things you
   expect. Pixelated graphics. Sprites. Limited color palette. At first
   glance, &lt;a href="http://www.realmofthemadgod.com"&gt;Realm of the Mad
God&lt;/a&gt; has retro graphics like many other
   games:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.wildshadow.com/.a/6a01156f7241f2970c0120a7c1e44e970b-800wi"&gt;&lt;img style="max-width:100%" src="http://blog.wildshadow.com/.a/6a01156f7241f2970c0120a7c1e44e970b-800wi" alt="Screenshot of Realm of the Mad God"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;However, Alex of &lt;a href="http://wildshadow.com"&gt;Wild  Shadow Studios&lt;/a&gt;  put in
   several things that  don't fit the usual retro  graphics approach. The
   above screenshot shows  that the world map and its  pixels rotate with
   the player,  while the trees, players, and  monsters stay axis-aligned
   (like  billboards  in  3d  games).  Weapon  projectiles  move  in  any
   direction, not only the usual 4 or 8 that you might expect from a game
   on a tile grid.
&lt;/p&gt;
&lt;p&gt;Less apparent is the variable scale. The “pixels” aren't simply
   magnified by a fixed amount. Each object has its own scale, which you
   can see in this screenshot by comparing the trees:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kV9ZnGnZL7M/S4sSOzZtyYI/AAAAAAAADWQ/UWh_2oN4JAE/s800/RotMG-Scale.png"&gt;&lt;img style="max-width:100%" src="http://lh4.ggpht.com/_kV9ZnGnZL7M/S4sSOzZtyYI/AAAAAAAADWQ/UWh_2oN4JAE/s800/RotMG-Scale.png" alt="Screenshot showing variable scale sprites"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Something that's easy to miss is that some effects have a shower of
   “pixels”. In this composite of three screenshots, you can see red
   “blood splatter” and some green remains of something that exploded (I
   think):
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kV9ZnGnZL7M/S4sSOl1lJhI/AAAAAAAADWE/brXji2ldyjA/s800/RotMG-Exploding-pixels-examples.png"&gt;&lt;img style="max-width:100%" src="http://lh3.ggpht.com/_kV9ZnGnZL7M/S4sSOl1lJhI/AAAAAAAADWE/brXji2ldyjA/s800/RotMG-Exploding-pixels-examples.png" alt="Screenshots showing pixel showers"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Also easy to miss is how the water effect breaks expectations of retro
   game art. The sprites themselves are pixelated, but the alignment
   doesn't match the map. With this, Alex produces water animation. Look
   closely at the sand and water boundary, and you'll see that the
   “pixels” don't match up:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kV9ZnGnZL7M/S4sSO_azIwI/AAAAAAAADWM/8xdxNX24pO0/s800/RotMG-Pixel-alignment.png"&gt;&lt;img style="max-width:100%" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/S4sSO_azIwI/AAAAAAAADWM/8xdxNX24pO0/s800/RotMG-Pixel-alignment.png" alt="Screenshot showing water and sand pixel misalignment"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;One of the neater effects in this game is the 3d dungeon walls. The
   ground, tops of walls, and sides of walls are all rendered with pixel
   art. In this screenshot you can see one of the players is behind the
   wall:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_kV9ZnGnZL7M/S4sSOYUCiTI/AAAAAAAADWA/Y0XY-nglD80/s800/RotMG-3d.png"&gt;&lt;img style="max-width:100%" src="http://lh3.ggpht.com/_kV9ZnGnZL7M/S4sSOYUCiTI/AAAAAAAADWA/Y0XY-nglD80/s800/RotMG-3d.png" alt="Screenshot showing underutilized 3d engine"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I drew some examples of things that could be interesting but aren't
   actually in the game at this time: dissolve effects (teleportation?),
   shadows (to show height), shearing (to show motion), rotated body
   parts or weapons (for improved animation), and outlines (to improve
   contrast or show effects like damage or buffs):
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_kV9ZnGnZL7M/S4sSOoN_3DI/AAAAAAAADWI/GY-_i0VciT8/s800/RotMG-More.png"&gt;&lt;img style="max-width:100%" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/S4sSOoN_3DI/AAAAAAAADWI/GY-_i0VciT8/s800/RotMG-More.png" alt="Potential effects that could be used with sprite art"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The sprite art we got from Oryx is pixel art, but in a vector graphics
   engine there are lots of things you can do with the sprite art.  For
   &lt;a href="http://blog.wildshadow.com/wild_shadow_studios/2010/01/realm-of-the-mad-god.html"&gt;Realm of the Mad
God&lt;/a&gt;,
   Alex played with rotation, scale, alignment, and 3d to produce some
   neat effects that you don't normally see in games with retro graphics.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7807899302486062319?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7807899302486062319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7807899302486062319' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7807899302486062319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7807899302486062319'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/02/retro-art-breaking-rules.html' title='Retro art: breaking the rules'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_kV9ZnGnZL7M/S4sSOzZtyYI/AAAAAAAADWQ/UWh_2oN4JAE/s72-c/RotMG-Scale.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3596193779651612045</id><published>2010-01-30T19:13:00.000-08:00</published><updated>2010-09-04T08:38:33.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Simple map generation</title><content type='html'>&lt;p&gt;My friends Alex and Rob at &lt;a href="http://www.wildshadow.com/"&gt;Wild Shadow Studios&lt;/a&gt; entered the &lt;a href="http://forums.tigsource.com/index.php?board=38.0"&gt;TIG Assemblee competition&lt;/a&gt;. In the first 30 days, artists create art assets, and in the second 30 days, programmers create games with those assets. Alex and Rob decided to write an MMO in those 30 days. They asked me about generating game maps.
&lt;/p&gt;
&lt;p&gt;In the past I had generated outdoor terrain maps by using randomness, erosion, and water flow (see &lt;a href="http://www-cs-students.stanford.edu/~amitp/games.html"&gt;the Simblob Project&lt;/a&gt;). However there was a terrible trap in there. I spent years refining the terrain generation system, and far too little time working on combat and the game itself. I had fun, but I never finished that game.
&lt;/p&gt;
&lt;p&gt;Wary of my tendencies to work on one aspect of a game too much while neglecting everything else, I decided this time to do something simple. I started with &lt;a href="http://en.wikipedia.org/wiki/Perlin_noise"&gt;Perlin Noise&lt;/a&gt;. I generated both a moisture map and an altitude map:
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_kV9ZnGnZL7M/S10BOAqdPCI/AAAAAAAADR0/rSrjUl5hcbI/s800/Map%20generator%20moisture%20and%20altitude.png" alt="Moisture and altitude maps"/&gt;
&lt;/p&gt;
&lt;p&gt;To ensure that some areas are dry and some areas are wet, I renormalized the moisture map to try to produce equal areas of every moisture level. I also renormalized the altitude map to produce far more flat and low lands than high altitudes, following a quadratic function. After renormalization every random map has a reasonable mix of land types.
&lt;/p&gt;
&lt;p&gt;From these I defined simple rules that assigned a vegetation. High
   altitudes are snowy mountaintops and low altitudes are ocean or
   beach. In between, the moisture determines how green or yellow the
   land is. Since most altitudes are not reflected in the map coloring, I
   added some shading so that it would be easier to see the mountains and
   valleys:
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://lh4.ggpht.com/_kV9ZnGnZL7M/S10B7_j3dHI/AAAAAAAADR8/Hisj40eX3ZM/s800/Map%20generator%20before%20wind%20algorithm.png" alt="Generated map"/&gt;
&lt;/p&gt;
&lt;p&gt;There were two things I wanted to add. The first was
   &lt;a href="http://simblob.blogspot.com/2009/06/noise-in-game-art.html"&gt;noise&lt;/a&gt;. I
   find noise to add to the visual appeal, and in this case it would
   also decrease the sharp boundaries between different terrain
   types. Compare this map to the original:
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_kV9ZnGnZL7M/S10HNCHIj6I/AAAAAAAADSE/hWJqyvYUWvM/s800/Map%20generator%20after%201%20wind%20step.png" alt="Generated map with a bit of noise"/&gt;
&lt;/p&gt;
&lt;p&gt;The second thing I wanted to add was wind. In many parts of the world, wind picks up moisture from the ocean and spreads it over the land. At mountains, much of this moisture is extracted from the wind and dropped as rain:
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www-cs-students.stanford.edu/~amitp/simblob/rain-shadow.png" alt="Rain shadow illustration"/&gt;
&lt;/p&gt;
&lt;p&gt;You can see this pattern in the United States, with winds out of the west dropping moisture in Oregon and California, passing over the Sierra Nevada mountains, leaving Utah and Arizona rather dry. In Australia, the winds come from the east, hit the Great Dividing Range, leaving the eastern coast wet and the interior of the continent dry. In South America, the winds come from the east but don't hit mountains until the Andes, so the rain falls over most of the continent, giving us the Amazon rainforest. I wanted the mountains in the game map to affect the moisture levels. I added a wind algorithm that spreads moisture from west to east and generated this map:
&lt;/p&gt;
&lt;p&gt;&lt;img src="http://lh5.ggpht.com/_kV9ZnGnZL7M/S10HNfzK4nI/AAAAAAAADSI/HIv0nrksX0g/s800/Map%20generator%20after%2010%20wind%20steps.png" alt="Generated map after wind spreads moisture from the west"/&gt;
&lt;/p&gt;
&lt;p&gt;You can see that the dry areas in the northwest are now green, and the southeast, where the moisture is blocked by mountains, is dry. It seems more “realistic” but I think the players don't really notice such things.
&lt;/p&gt;
&lt;p&gt;In the demo app you can click on the minimap to see the zoomed area, change the number of wind algorithm iterations (then press Update), randomize the map seed (the Randomize button), or type in a random number seed and press Update. I find that 83980, 59695, 94400, 92697, 30628, 9146, 23896, 60489, 57078, 89680, 10377, 42612, and 29732 are seeds that produce decent maps. The demo differs a little bit from what we used in the game but the overall map shape and features are the same.
&lt;/p&gt;
&lt;p&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="775" height="540" id=""&gt;
     &lt;param name="movie" value="http://www-cs-students.stanford.edu/~amitp/game-programming/mapgen-realm-of-the-mad-god/mapgen.swf"&gt;
     &lt;object type="application/x-shockwave-flash" data="http://www-cs-students.stanford.edu/~amitp/game-programming/mapgen-realm-of-the-mad-god/mapgen.swf" width="775" height="540"&gt;
     &lt;/object&gt;
   &lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;For &lt;a href="http://realmofthemadgod.com"&gt;Realm of the Mad God&lt;/a&gt; we exported the map and then made vegetation and monsters based on the terrain characterstics. The tree density was higher in jungles than on hills, rocks mostly were on mountains, and dead trees littered the deserts. Monsters too were terrain-specific at first, but they ended up spreading throughout the land. On top of the map we added random temple ruins and were hoping to make those areas special in some way, but ran out of time.
&lt;/p&gt;
&lt;p&gt;Looking back on this project, there were lots of things I did that don't really matter to the players. I tried to make the algorithms “scale independent” so that I could generate maps of different sizes and they'd end up with similar features, but in practice we only wanted maps of 2048x2048. The noise, which looks good in the overview map, looks awful when playing the game, so we ended up smoothing it out. I tried to make a two-step process that would generate the large scale features with one algorithm and the details with a different algorithm, and I never got that working well; I ended up just generating everything with the large scale algorithm. I had a river algorithm that carved out canyons, and I didn't get it working well enough in time for the game contest. I tried several ways to make the edges of the map into oceans (so that players would never reach the edge of the map) but none of them worked out, and players didn't seem to mind reaching the edge. The edges of the map never worked out right because bands of weirdness would form (you can see this in the demo). The simplest thing would've been to cut off the edges.
&lt;/p&gt;
&lt;p&gt;There were also lots of things I'd like to add, but probably shouldn't because I should move on to other projects. It would've been nice to create a map rating algorithm that could automatically pick out maps that look good (plenty of water, beach, mountains, variety, etc.). But for Realm of the Mad God we just looked at a bunch of maps and picked seed 72689. It was a pretty nice looking map, except the peninsula turned out to be a little frustrating for players, and we don't want the bosses to spawn on islands that players can't reach. For the expansion pack we'll probably just pick a few random seeds that look good and make maps from them. It would've been nice to automatically pick spawn points for players and monsters but those too were just placed manually. It would also be nice if there were some landmarks and regions with names so that the players could talk about where they were. 
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://realmofthemadgod.com/"&gt;Try the game&lt;/a&gt; and see how different it
   feels to be exploring the map in the game than it does to look at it
   in the demo app. For example, the god monsters live on the mountains;
   it's much easier to see where these are on the map than to figure it
   out while playing the game. I think the 30 day time limit really
   helped keep me focused on things that would be useful for players.
   After the contest was over I found I was spending time on much less
   important things. I'm planning to stop working on the map generator
   for now, and only revisit it if there are specific features I need to
   add. The &lt;a href="http://github.com/amitp/mapgen"&gt;source&lt;/a&gt; is available under
   the MIT license (however the &lt;a href="http://forums.tigsource.com/index.php?topic=8970.0"&gt;Oryx tileset&lt;/a&gt; is not licensed the same way so the version I put
   on github uses solid colors instead).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3596193779651612045?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3596193779651612045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3596193779651612045' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3596193779651612045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3596193779651612045'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2010/01/simple-map-generation.html' title='Simple map generation'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_kV9ZnGnZL7M/S10BOAqdPCI/AAAAAAAADR0/rSrjUl5hcbI/s72-c/Map%20generator%20moisture%20and%20altitude.png' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7566338080989944510</id><published>2009-11-08T16:50:00.000-08:00</published><updated>2009-11-08T17:04:37.079-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Flash 10: drawTriangles() disappointments</title><content type='html'>&lt;p&gt;I've been switching to Flash 10 for my game experiments. Flash 10
   offers new graphics APIs, and opens up new approaches for how to deal
   with game objects.  I wanted to compare these approaches:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;
     (Flash 9) Use multiple &lt;code&gt;Sprite&lt;/code&gt; objects for hierarchical layers, filters, rotation, and translation. It's convenient to have one or more Sprites per game object, and then move and rotate them without having to manage them manually. For vector drawing, I can use &lt;code&gt;beginFill&lt;/code&gt; and &lt;code&gt;lineStyle&lt;/code&gt; with (Flash 10) &lt;code&gt;drawPath&lt;/code&gt;. For bitmap (textured) drawing, I can use &lt;code&gt;beginBitmapFill&lt;/code&gt;, or there's a special &lt;code&gt;Bitmap&lt;/code&gt; class for rectangular bitmaps.
 &lt;/li&gt;

 &lt;li&gt;
     (Flash 10) Manage my own list of objects, and then build up a vector of &lt;code&gt;IGraphicsData&lt;/code&gt; objects, and pass that to &lt;code&gt;Graphics.drawGraphicsData&lt;/code&gt;. This puts the burden on me to handle translation and rotation, and I don't see a great way to add filters. Here too I can use either &lt;code&gt;beginFill&lt;/code&gt; + &lt;code&gt;lineStyle&lt;/code&gt; or &lt;code&gt;beginBitmapFill&lt;/code&gt; for vector or bitmap drawing.
 &lt;/li&gt;

 &lt;li&gt;
     (Flash 10) Manage my own list of objects, build up a vector of vertices and another vector of texture coordinates, and use &lt;code&gt;Graphics.drawTriangles&lt;/code&gt;. I have to handle translation and rotation of the vertices, but Flash will handle the translation, rotation, and scaling of the textures. 
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that there's actually a lot more flexibility than just three
   options. There are three ways to draw polygons (&lt;code&gt;lineTo&lt;/code&gt;, &lt;code&gt;drawPath&lt;/code&gt;,
   or &lt;code&gt;drawTriangles&lt;/code&gt;), two object management approaches (using
   &lt;code&gt;Sprite&lt;/code&gt;, or managing the list manually), and whether to defer
   drawing using &lt;code&gt;IGraphicsData&lt;/code&gt;.  Which approach should I use for a game
   like &lt;a href="http://simblob.blogspot.com/2009/03/game-component-spaceship-editor-part-4.html"&gt;my spaceship
demo&lt;/a&gt;?

&lt;/p&gt;

&lt;h3&gt;Convenience&lt;/h3&gt;
&lt;p&gt;One of the things I love about Flash is that drawing is pretty
   convenient, especially with &lt;code&gt;Sprite&lt;/code&gt; objects, bitmap handling,
   translation/rotation, easy filters like drop shadow, and vector
   drawing. For example:
&lt;/p&gt;
&lt;pre&gt;var s:Sprite = new Sprite();
s.beginBitmapFill(texture, null, false, true);
s.drawPath
  (Vector.&amp;lt;int&amp;gt;([1, 2, 2, 2]),
   Vector.&amp;lt;Number&amp;gt;([100, 0, 164, 0, 164, 64, 100, 64]));
s.endFill();
&lt;/pre&gt;&lt;p&gt;To rotate or translate the game objects, set the &lt;code&gt;s.x&lt;/code&gt;, &lt;code&gt;s.y&lt;/code&gt;, and
   &lt;code&gt;s.rotation&lt;/code&gt; fields.  When you need a new game object, instantiate a
   &lt;code&gt;Sprite&lt;/code&gt; and insert it into the hierachy; when you want to remove one,
   remove the shape. Flash handles the rest.

&lt;/p&gt;
&lt;p&gt;With Flash 10, the &lt;code&gt;IGraphicsData&lt;/code&gt; interface lets you store graphics
   commands in objects, and then draw with them later. You can either
   call commands similar to the Flash 9 API, or you can store graphics
   data in a more direct form.  Once you've assembled all the graphics
   objects, you can draw them all using &lt;code&gt;Graphics.drawGraphicsData&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;v[0] = new GraphicsBitmapFill(texture, null, false, true);
v[1] = new GraphicsPath
   (Vector.&amp;lt;int&amp;gt;([1, 2, 2, 2]),
    Vector.&amp;lt;Number&amp;gt;([100, 0, 164, 0, 164, 64, 100, 64]));
v[2] = new GraphicsEndFill();
graphics.drawGraphicsData(v);
&lt;/code&gt;&lt;/small&gt;&lt;/pre&gt;&lt;p&gt;You can draw each of these to a separate &lt;code&gt;Sprite&lt;/code&gt;, or you can assemble
   them all into one big vector and make a single call to
   &lt;code&gt;Graphics.drawGraphicsData&lt;/code&gt;.  The main value I think is to be able to
   batch them up, so I decided to make a single call, but that means I
   need to manage translation and rotation myself.  Instead of creating
   new graphics data objects, you can update them every frame.  Each of
   my game objects can keep a reference to where in the graphics data
   array it is represented, and then when I want to update the game
   object, I can change the corresponding &lt;code&gt;GraphicsPath&lt;/code&gt; object. For
   rotation, I need to edit the path and also the bitmap rotation in the
   &lt;code&gt;GraphicsBitmapFill&lt;/code&gt; object.

&lt;/p&gt;
&lt;p&gt;Adding and removing game objects is a little trickier. Either I can
   rebuild the entire vector every time, or I can build something similar
   to a memory allocator, so that I can reuse parts of the vector. I
   haven't yet decided how I'm going to handle this (my tests so far have
   a fixed number of game objects).
&lt;/p&gt;
&lt;p&gt;The Flash 10 &lt;code&gt;Graphics.drawTriangles&lt;/code&gt; interface is somewhat
   inconvenient when working with 2D data. It requires that all polygons
   be decomposed into triangles (not hard to do but it's an extra
   step). The function takes a list of vertices, a list of indices that
   point into the vertex vector, and texture coordinates.
&lt;/p&gt;
&lt;pre&gt;graphics.beginBitmapFill(texture, null, false, true);
graphics.drawTriangles
 (Vector.&amp;lt;Number&amp;gt;([100, 0, 164, 0, 164, 64, 100, 64]),
  Vector.&amp;lt;int&amp;gt;([0, 1, 2, 2, 3, 0]),
  Vector.&amp;lt;Number&amp;gt;([0, 0, 1, 0, 1, 1, 0, 1]));
graphics.endFill();
&lt;/pre&gt;&lt;p&gt;Here too I need to handle translation and rotation myself, by updating
   the vector. However I don't need to rotate the bitmaps because
   &lt;code&gt;drawTriangles&lt;/code&gt; takes care of this for me.  Adding and removing
   objects is similar to the previous case, in that I need to handle it
   myself.

&lt;/p&gt;
&lt;p&gt;Overall, the traditional API is most convenient, but deferring the
   &lt;code&gt;drawPath&lt;/code&gt; by putting it into a &lt;code&gt;GraphicsDataPath&lt;/code&gt; is convenient
   too. The &lt;code&gt;drawTriangles&lt;/code&gt; interface is least convenient, except for not
   needing to rotate bitmaps.
&lt;/p&gt;

&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;I've found that my intuition hasn't been a great guide for
   understanding Flash performance. My intuition told me that approach 1
   (&lt;code&gt;Sprite&lt;/code&gt; objects) would be slower than approach 2 (global graphics
   data list), and approach 3 (triangles) would be fastest of all.

&lt;/p&gt;
&lt;p&gt;I wrote a test program that drew 400–1000 square objects on the screen
   at once and moved them around. I also put in options for rotation
   (because many of the objects in the spaceship demo were rotating), use
   bitmap or vector graphics (&lt;a href="http://simblob.blogspot.com/2009/06/noise-in-game-art.html"&gt;I like noise in
art&lt;/a&gt; and
   bitmaps seem to be the way to make that), using outlines for vector
   graphics (&lt;a href="http://blog.wildshadow.com/wild_shadow_studios/2009/07/dreadnought.html"&gt;I like
outlines!&lt;/a&gt;),
   and animating bitmaps.
&lt;/p&gt;
&lt;p&gt;My general conclusions, for this style of game:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;
     Vector graphics are faster than bitmap graphics (especially when rotation is involved), but that using outlines on the vector graphics slows them down, about as much as bitmaps do. Also, if the vector graphics have any additional complexity, the bitmaps end up being faster. Since I almost always want outlines or some other edge effect, bitmaps shouldn't cost me that much, and they'll give me a lot more options for adding details.
 &lt;/li&gt;

 &lt;li&gt;
     Using the separate &lt;code&gt;Sprite&lt;/code&gt; objects is about the same speed as using a single &lt;code&gt;IGraphicsData&lt;/code&gt; vector. Sprite objects are more convenient. However, once I want animation, the &lt;code&gt;IGraphicsData&lt;/code&gt; approach shines: I can swap in alternative paths and bitmaps at no cost, whereas with drawing directly, I have to redraw to get animation (it's possible that I can create lots of &lt;code&gt;Sprite&lt;/code&gt; objects and then swap them out but I haven't tried this).
 &lt;/li&gt;

 &lt;li&gt;
     For consistent frame rates, it's best to minimize allocation, and reuse some objects. The &lt;code&gt;IGraphicsData&lt;/code&gt; objects, the vector of them, and the vectors fo vertex and index data all can be reused from frame to frame, with additional complexity to track where everything is.
 &lt;/li&gt;

 &lt;li&gt;
     With the triangle API, I can put all my textures into one big bitmap, and then access them using texture coordinates. This allows me to make a single &lt;code&gt;drawTriangles&lt;/code&gt; call. However, using hundreds of of &lt;code&gt;GraphicsBitmapFill&lt;/code&gt; and &lt;code&gt;GraphicsDrawPath&lt;/code&gt; objects is suprisingly faster than using a single &lt;code&gt;drawTriangles&lt;/code&gt; call. I was unable to make the triangle approach faster. 
 &lt;/li&gt;

&lt;/ol&gt;
&lt;p&gt;The performance of &lt;code&gt;drawTriangles&lt;/code&gt; (even when I used
   &lt;code&gt;GraphicsTrianglePath&lt;/code&gt;) was a disappointment. My thanks to Alex from &lt;a href="http://blog.wildshadow.com/wild_shadow_studios/gamehalf/"&gt;Wild Shadow Studios&lt;/a&gt; for his help in understanding the APIs and performance.
&lt;/p&gt;

&lt;h3&gt;Rendering&lt;/h3&gt;
&lt;p&gt;It wasn't enough for &lt;code&gt;drawTriangles&lt;/code&gt; to be slower for this type of game. I've also had issues with the bitmap rendering. Here's a 64x64 test image drawn in several ways:
&lt;/p&gt;
&lt;img align="right" style="max-width:100%" src="http://lh3.ggpht.com/_kV9ZnGnZL7M/SvdH8splyDI/AAAAAAAABzk/VUJW70L5j9s/s800/Bitmap%20fills%20in%20Flash%2010.png" alt="8 test images showing various Flash drawing methods"&gt;

&lt;ol&gt;
 &lt;li&gt;
     A &lt;code&gt;Bitmap&lt;/code&gt; object.
 &lt;/li&gt;

 &lt;li&gt;
     A polygon drawn with &lt;code&gt;beginBitmapFill&lt;/code&gt;.
 &lt;/li&gt;

 &lt;li&gt;
     A &lt;code&gt;Bitmap&lt;/code&gt; object rotated 90 degrees clockwise.
 &lt;/li&gt;

 &lt;li&gt;
     A polygon drawn with &lt;code&gt;beginBitmapFill&lt;/code&gt;, rotated 90 degrees.
 &lt;/li&gt;

 &lt;li&gt;
     Two triangles drawn with &lt;code&gt;drawTriangles&lt;/code&gt;, and u/v range from 0 to 1.
 &lt;/li&gt;

 &lt;li&gt;
     Same as 5, except u/v adjusted by 1/64.
 &lt;/li&gt;

 &lt;li&gt;

     Same as 5, rotated 90 degrees.
 &lt;/li&gt;

 &lt;li&gt;
     Same as 6, rotated 90 degrees.
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that images &lt;strong&gt;1&lt;/strong&gt; and &lt;strong&gt;2&lt;/strong&gt; look the same. This is as it should
   be. If I believe the documentation, image &lt;strong&gt;5&lt;/strong&gt; should look the same as &lt;strong&gt;1&lt;/strong&gt;

   and &lt;strong&gt;2&lt;/strong&gt;. But it doesn't.
&lt;/p&gt;
&lt;p&gt;As far as I can tell, &lt;code&gt;drawTriangles&lt;/code&gt; is assigning a u/v coordinate of
   1.0 to be pixel 62 instead of pixel 63. If you look closely, you can
   see the gray pixels are getting blurred (stretched). A “fix” for this
   is in image &lt;strong&gt;6&lt;/strong&gt;, where I set the u/v coordinate to 1.0 + 1/64, so
   that it picks pixel 63. With this hack, the image matches the
   reference image &lt;strong&gt;1&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;Images &lt;strong&gt;3&lt;/strong&gt; and &lt;strong&gt;4&lt;/strong&gt; are the same as &lt;strong&gt;1&lt;/strong&gt; and &lt;strong&gt;2&lt;/strong&gt;, but rotated 90
   degrees clockwise. Images &lt;strong&gt;7&lt;/strong&gt; and &lt;strong&gt;8&lt;/strong&gt; are the same as &lt;strong&gt;5&lt;/strong&gt; and
   &lt;strong&gt;6&lt;/strong&gt;, rotated 90 degrees clockwise.  Notice that &lt;strong&gt;7&lt;/strong&gt; is incorrect
   (it should match &lt;strong&gt;3&lt;/strong&gt;), but it's incorrect in a different way than
   &lt;strong&gt;5&lt;/strong&gt;. Instead of losing the yellow and blue edges, it loses the green
   and yellow edges. The hack in image &lt;strong&gt;6&lt;/strong&gt;, when applied to &lt;strong&gt;8&lt;/strong&gt;,
   fails. That means it's not as obvious as pixel 62 instead of 63; there
   must be a weirder issue that I don't understand.

&lt;/p&gt;
&lt;p&gt;These issues with &lt;code&gt;drawTriangles&lt;/code&gt; rendering make it hard to recommend
   for 2D graphics. I don't need everything to be exactly the same, but I
   do plan to draw 1-pixel outlines around my sprites, and
   &lt;code&gt;drawTriangles&lt;/code&gt; can't preserve the outline. Even worse, as I rotate my
   game's objects, the outlines will appear and disappear.
&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;drawTriangles&lt;/code&gt; API also has some weird effects when using Flash's
   built in zoom function (right click and choose Zoom In). It also
   doesn't seem to be happy when using bitmap fills with &lt;code&gt;repeat&lt;/code&gt; set to
   true. And it doesn't seem to handle texture scaling as well as the
   regular APIs (it's possible they aren't using
   &lt;a href="http://www.kaourantin.net/2007/06/mip-map-what.html"&gt;mipmaps&lt;/a&gt;).

&lt;/p&gt;

&lt;h3&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;For both convenience and performance for games like my spaceship demo,
   I think I should have every game object store some &lt;code&gt;IGraphicsData&lt;/code&gt;
   objects, and also store a vector of all of them. I had thought that
   &lt;code&gt;drawTriangles&lt;/code&gt; might be better, but it's both slower and less
   convenient. It also doesn't look as good. I think I might take a look
   at &lt;code&gt;drawTriangles&lt;/code&gt; for 3D perspective graphics, or if I had lots of
   triangle data, but for 2D or orthographic 3D, I think it's probably
   not the best choice for me right now.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7566338080989944510?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7566338080989944510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7566338080989944510' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7566338080989944510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7566338080989944510'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/11/flash-10-drawtriangles-disappointments.html' title='Flash 10: drawTriangles() disappointments'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_kV9ZnGnZL7M/SvdH8splyDI/AAAAAAAABzk/VUJW70L5j9s/s72-c/Bitmap%20fills%20in%20Flash%2010.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3818658086702393518</id><published>2009-08-18T16:00:00.000-07:00</published><updated>2009-08-18T16:00:18.074-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Parallel World Simulation</title><content type='html'>&lt;p&gt;When playing long simulation/strategy games like SimCity, Roller
   Coaster Tycoon, or Civilization, I often have “what if” questions:
   what if I built an airport there? what if I invaded Albania? what if I
   switched to solar power? what if I built extra police stations?
&lt;/p&gt;
&lt;p&gt;My usual answer is to just keep wondering. However if I'm very
   motivated I can save the game, try something, save it again, go back
   to the first save game, try the other option, and then compare the
   results. It's rather tedious, so I don't do it much.
&lt;/p&gt;
&lt;p&gt;It might be interesting to bring the “what if” gameplay into the game
   itself, instead of being outside of it, as save games. Games like
   &lt;a href="http://www.kongregate.com/games/Scarybug/chronotron"&gt;Chronotron&lt;/a&gt; and
   &lt;a href="http://braid-game.com/"&gt;Braid&lt;/a&gt; allow you to go back and try something
   else, and even see past paths while you're playing through
   again. &lt;a href="http://www.bungie.net/Online/Heatmaps.aspx"&gt;Halo 3 heatmaps&lt;/a&gt;
   aggregate information from a huge number of games. I think these ideas
   apply to simulation/strategy games too.

&lt;/p&gt;
&lt;p&gt;Imagine if you could “split” the timeline into two and watch parallel
   worlds evolve simultaneously:
&lt;/p&gt;
&lt;p&gt;
&lt;img width="99%" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SospdSvNqwI/AAAAAAAABCc/GyLVw7G9ElI/s800/Parallel%20Universe%20side%20by%20side.png" alt="Side by side parallel universes"&gt;
&lt;/p&gt;

&lt;p&gt;If it's just a matter of running parallel worlds, I could do this by
   running the game twice, in two side by side windows.  However if it was
   integrated into the game there's some potential for interesting gameplay:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;The game could run two worlds all the time. Every 5 minutes the
   game could ask you which world is better, and then copy that world
   to both windows. You could run experiments but they're all limited
   to 5 minutes. You'd be able to learn by experimentation and then
   use that knowledge in the future.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;The game could run one world most of the time, but then in a
   world-splitting event, split into two. In one world you'd be asked
   to destroy; in the other, to build. You'd gain bonus points for
   maximizing the difference between the worlds.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;The game could let you play in one window and show in the other
   window the accumulated plays from your previous games on the same
   map, or perhaps from other people's games. Differences in play
   would be highlighted, and you'd gain points for novel play
   styles. In Halo, you might get a bonus for a sniper shot from a
   location where few people succeed making a sniper shot.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;In a multiplayer setting, each player could play in her own
   world for a few minutes, and then the game would ask everyone to
   vote for their favorite world other than their own, and then that
   world would become the baseline for the next round of play. It
   might be possible to integrate this into a Facebook game that you
   play asynchronously with your friends.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;If playing against a computer AI, it might be fair to let the
   computer player occasionally choose which world it prefers. The
   strategy would then be to set up a world that appears to give you
   a disadvantage without actually doing so. The Chess equivalent
   would be to intentionally sacrifice a rook in order to set up a
   winning move.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I'd love to see games explictly tackle parallel worlds, individually
   and in aggregate.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3818658086702393518?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3818658086702393518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3818658086702393518' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3818658086702393518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3818658086702393518'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/08/parallel-world-simulation.html' title='Parallel World Simulation'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_kV9ZnGnZL7M/SospdSvNqwI/AAAAAAAABCc/GyLVw7G9ElI/s72-c/Parallel%20Universe%20side%20by%20side.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7076267789001771418</id><published>2009-07-26T15:06:00.001-07:00</published><updated>2009-07-26T15:06:41.160-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><title type='text'>Storytelling with Comics</title><content type='html'>&lt;p&gt;In my &lt;a href="http://simblob.blogspot.com/2009/04/animating-stick-figures.html"&gt;post about drawing
ninjas&lt;/a&gt;,
   I mentioned that I had an idea for blending comic books and games, and
   I was trying to figure out where that idea came from. Most of the
   ideas I have are combinations of other ideas, and occasionally they're
   an idea I saw a long time ago, absorbed, completely forgot about, and
   then had it surface again.  I think this idea was sparked from a
   combination of things:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;After reading Scott McCloud's &lt;a href="http://en.wikibooks.org/w/wiki.phtml?title=Transwiki:Understanding_Comics"&gt;Understanding
  Comics&lt;/a&gt;,
     the comparison of time and space stuck in my head. Games,
     videos, and audio present a sequences temporally, but books and
     comics present those temporal sequences by laying them out
     spatially. Are there games that use the spatial layout of time?
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;I played &lt;a href="http://www.wired.com/gaming/gamingreviews/commentary/games/2008/04/gamesfrontiers_421"&gt;Passage&lt;/a&gt;,
     a game that represents time as a spatial dimension.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;I played &lt;a href="http://en.wikipedia.org/wiki/A_Tale_in_the_Desert"&gt;A Tale in the Desert&lt;/a&gt;, a massively multiplayer game in which a story unfolds from the collective actions of players. I had also played World of Warcraft, in which all the regular monsters get reset too often to make a lasting difference, but even there I saw story-worthy events (huge raids on cities, large social activities). But how are these recorded?
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;I got a new computer, which came with a neat little program called &lt;a href="http://plasq.com/comiclife"&gt;Comic Life&lt;/a&gt;. This application makes it easy to create comic strips and add thought/speech bubbles.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;I played Oblivion, in which I'm playing through a story. The quest NPCs know what part of the story I'm on, and can react appropriately. But it's a big open world and I can do lots of things, including side quests for various guilds. Unfortunately the tale of what I &lt;em&gt;actually&lt;/em&gt; did isn't anywhere; what's encoded in the game is what I'm &lt;em&gt;supposed&lt;/em&gt; to do on the main quest.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Sims and Spore are also storytelling games but the stories I read
   were outside the game itself.  In strategy games, I want to see the
   history of battles on the map. In adventure games, I want to see the
   history of my progress, not only successes but also failures.  Sports
   games aren't just about who won but about the great events during the
   games. In Chess I often want to see just the key moves that turned the
   game. Some of these games have timelines or replays or screenshots,
   which help with what I'm looking for, but they don't go far
   enough.
&lt;/p&gt;
&lt;p&gt;Comic books seem like a nice medium for recording history.  At the
   extreme, I could imagine using the comic book format for both the
   history and the “live” game.  The rightmost panel would be the game,
   and the other panels would show what you've done:
&lt;/p&gt;
&lt;p style="max-width: 100%"&gt;&lt;img src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SmzPp929c1I/AAAAAAAAA_4/6L0cNUEfchw/s800/comic-history.png" /&gt;&lt;/p&gt;

&lt;p&gt;As you play, “screenshots” of the significant events turn into static
   panels, which scroll off to the left. At the end of each chapter/level
   you can go back and see the history of what you did.  At the end of
   the game you can go back to see the entire game history, and then if
   you want, you would annotate it (with speech bubbles etc.)  and share
   it with friends. You could click on those panels to show a replay of
   that event. The are plenty of open questions here: what are the most
   significant events? What screenshot do you pick to convey the event?
   How many events do you want to capture? Should you ask the player to
   replay the event and pick the best point? Does this format give people
   enough context to understand the story? Will anyone want to share
   these stories?
&lt;/p&gt;
&lt;p&gt;It was with that idea in mind that I started working on the ninja
   animation. However, I lost interest in that (I seem to lose interest
   in lots of things I start) and don't know if I will ever return to it.
   I still think keeping history and stories hasn't been explored enough
   in games, and in just about every game I play, I can think of features
   that would help with history/stories. Storage has become very cheap;
   let's record a lot more.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7076267789001771418?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7076267789001771418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7076267789001771418' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7076267789001771418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7076267789001771418'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/07/storytelling-with-comics.html' title='Storytelling with Comics'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_kV9ZnGnZL7M/SmzPp929c1I/AAAAAAAAA_4/6L0cNUEfchw/s72-c/comic-history.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3795489375354611439</id><published>2009-06-28T18:08:00.000-07:00</published><updated>2009-07-26T15:08:25.586-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Noise in game art</title><content type='html'>&lt;p&gt;If you look at the artwork in old 2D 8-bit games, you see a lot of
   noise and dithering in the hand-drawn bitmap art. For an example, take
   a look at the grass or concrete in this Transport Tycoon screenshot:
&lt;/p&gt;
&lt;p style="max-width:100%; max-height: 200px; overflow:hidden"&gt;
&lt;a href="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s1600-h/Tunnel+stations.png"&gt;&lt;img src="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s1600/Tunnel+stations.png" alt="Transport Tycoon screenshot"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;When the gaming world moved to 3D 32-bit vector art, we lost some of
   that level of detail. We got lots of smooth areas. Eventually we mostly got the detail back by applying
   textures to the polgons. However, it often looks worse to
   me than the old hand-drawn art.
&lt;/p&gt;
&lt;p&gt;With my Flash experiments, I've been playing with 2D procedural vector
   art, and I've been trying to figure out how to make it look nicer
   without drawing textures by hand.  The simplest thing I found has been
   to apply noise to the art. On the left is some terrain without noise
   and on the right is some with noise:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="display:inline-block;max-width:48%;overflow:hidden"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/wDl-wWIMroeqysjH3Acp5w?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_kV9ZnGnZL7M/SkgDtRR-PmI/AAAAAAAAA6E/4qHgZJcZGOI/s800/without%20noise.png" alt="Test image without noise" /&gt;&lt;/a&gt;&lt;/span&gt;
&lt;span style="display:inline-block;max-width:48%;overflow:hidden"&gt;&lt;a href="http://picasaweb.google.com/lh/photo/ChWeQNvdm9W8W6YzQ3ObPQ?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_kV9ZnGnZL7M/SkgDtcH5PcI/AAAAAAAAA6I/ZnBPIiqTAXg/s800/with%20noise.png" alt="Test image with noise" /&gt;&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;

&lt;p&gt;I like the noisy version &lt;em&gt;much&lt;/em&gt; better.

&lt;/p&gt;
&lt;p&gt;The noise layer is fairly easy to apply; I use &lt;code&gt;BitmapData.noise()&lt;/code&gt; to
   generate it, and then use &lt;code&gt;BlendMode.ADD&lt;/code&gt; to add it to the original layer.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  var noiseTexture:BitmapData = new BitmapData(128, 128);
  noiseTexture.noise(Math.round(Math.random()*65536), 
                     0, 8, 7, true);
  var noise:Shape = new Shape();
  noise.graphics.beginBitmapFill(noiseTexture);
  noise.graphics.drawRect(0, 0, size, size);
  noise.graphics.endFill();
  layer.draw(noise, null, null, BlendMode.ADD);
  noiseTexture.dispose();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It's nice in that it inherits the color already there; the noise
   doesn't impose its own colors. However, this only works nicely on my
   background terrain, and it feels somewhat slow on my low-end machine.
&lt;/p&gt;
&lt;p&gt;For foreground sprites, the noise layer doesn't move when those
   sprites move or rotate. An alternative would be to draw the noise on
   top of my sprites, using &lt;code&gt;Graphics.beginBitmapFill()&lt;/code&gt;, but that would
   require that I have a way to compute the outline of my procedural art,
   so that I can draw the noise on top as a polygon. Another alternative
   would be to use bitmap fills for every polygon, but that requires that
   I have a noise bitmap for each color. And yet another alternative is
   to draw every polygon twice, once for the color and once for the
   noise.
&lt;/p&gt;

&lt;p&gt;With Flash 10 I had hoped that the &lt;a href="http://labs.adobe.com/technologies/pixelbender/"&gt;pixel
shaders&lt;/a&gt; would allow
   me to apply noise to anything. I played around with them a bit. The shader
   receives the output coordinates in a function &lt;code&gt;outCoord()&lt;/code&gt;, and can
   compute a color for that location. It can optionally include
   parameters (like a noise bitmap). The big problem is that the output
   coordinates &lt;em&gt;are in screen space&lt;/em&gt;. This means that when the sprite
   moves or rotates, or if you zoom in, the noise would stay fixed
   relative to the screen. I tried both using shaders for fills and
   shaders for filters, and neither gave me what I wanted.
&lt;/p&gt;
&lt;p&gt;That's a serious problem for my use. To address this problem, I can
   pass in additional parameters like rotation and offset. However, I
   have to re-fill the shape every time I change the shader
   parameters. Even worse, the pixel shader &lt;a href="http://www.kaourantin.net/2008/05/adobe-pixel-bender-in-flash-player-10.html"&gt;is recompiled every time you
fill&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;So it looks like pixel shaders in Flash 10 just don't do what I want.
   I want a way to get the pixel's location in the sprite's coordinate
   system, after transforms are applied, but instead I only get the screen's
   coordinate system.
&lt;/p&gt;
&lt;p&gt;I think my best bet for performance is to not apply noise to vector
   backgrounds (applying noise to a bitmap won't impact
   performance). This will make me sad but smoothness matters a great
   deal. I should also try using tiles to see if that is any faster. For
   foreground objects, it's probably not too bad to draw everything
   twice, but I'll have to test this. It may not matter if I switch to
   bitmap sprites eventually; they'd let me draw a lot more details.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3795489375354611439?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3795489375354611439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3795489375354611439' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3795489375354611439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3795489375354611439'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/06/noise-in-game-art.html' title='Noise in game art'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s72-c/Tunnel+stations.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-523180181005764904</id><published>2009-06-20T16:19:00.001-07:00</published><updated>2011-10-03T13:51:07.329-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Switching to Flash 10</title><content type='html'>&lt;p&gt;On this blog you can see some of the experiments I've been playing
   with. In 2004, I started &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-flash.html"&gt;looking at Flash&lt;/a&gt;, mostly because I'd be
   able to share my experiments on the web. But at the time, Flash wasn't
   as free or accessible, and I &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-java.html"&gt;switched to Java&lt;/a&gt;. Dissatisfied with
   Java, I took a look at Flash again, and &lt;a href="http://simblob.blogspot.com/2006/12/learning-flash.html"&gt;started writing Flash 8
code&lt;/a&gt;. Two years ago I &lt;a href="http://simblob.blogspot.com/2007/06/learning-flash-9.html"&gt;switched from Flash 8 to Flash 9&lt;/a&gt;.
   Flash 9's language (Actionscript 3) is much nicer than Flash 8's
   language (Actionscript 2). It's a modern programming language, with
   classes, objects, closures, recursion, XML, JSON, etc., and was
   tracking ECMAscript until the Javascript folk changed direction. Flash
   9's graphics libraries are nicer than Flash 8's. It supports a tree of
   layers, each with its own rotation, scaling, alpha transparency,
   shadows, and other effects.
&lt;/p&gt;
&lt;p&gt;Flash 10 uses the same language as Flash 9. Its libraries have lots
   more features, especially in the graphics system. There's now a
   &lt;a href="http://www.senocular.com/flash/tutorials/flash10drawingapi/"&gt;low-level graphics API&lt;/a&gt; that offers partial 3D, higher
   performance, and &lt;a href="http://labs.adobe.com/technologies/pixelbender/"&gt;pixel shaders&lt;/a&gt;.  I was slow to move to
   Flash 9 in part because the adoption of Flash 9 was slow. It looks
   like Flash now has auto-updating, and Flash 10 is being installed
   &lt;a href="http://www.adobe.com/products/player_census/flashplayer/version_penetration.html"&gt;much more widely&lt;/a&gt;. I'm switching all my current projects to
   Flash 10.

&lt;/p&gt;
&lt;p&gt;For Flash 10 I'm using the &lt;a href="http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex3sdk"&gt;&lt;strong&gt;free Flex 3.3 SDK&lt;/strong&gt;&lt;/a&gt; and the Flex
   3.3 docs (&lt;a href="http://livedocs.adobe.com/flex/3/langref/"&gt;online&lt;/a&gt; or &lt;a href="http://livedocs.adobe.com/flex/3/flex3_documentation.zip"&gt;download&lt;/a&gt;). The
   SDK comes with a command line compiler, &lt;code&gt;mxmlc&lt;/code&gt;, that I run
   with &lt;kbd&gt;mxmlc -target-player 10&lt;/kbd&gt; on the “main” program, and
   that will also compile anything else that is used by the main
   class. If you want a tutorial for using &lt;code&gt;mxmlc&lt;/code&gt;, see
   &lt;a href="http://www.senocular.com/flash/tutorials/as3withmxmlc/"&gt;senoular's mxmlc beginner
guide&lt;/a&gt;.

&lt;/p&gt;
&lt;p&gt;Flex also comes with a compilation shell, &lt;code&gt;fcsh&lt;/code&gt;, that lets
   you keep the compiler in memory to avoid the 2 seconds to start it up
   every time you want to recompile. I wrote a wrapper around this so
   that whenever I save something in Emacs, it automatically recompiles.
   That way, my development cycle is: edit, save, and reload in the
   browser. It's quite nice to have a fast cycle.
&lt;/p&gt;
&lt;p&gt;I haven't played much with the Flash 10 library additions, but the
   first thing I used was the bitmap line support. I'm using it to draw
   dashed lines as &lt;a href="http://wiki.github.com/amitp/containerport/intersections"&gt;striped lane dividers&lt;/a&gt;. I plan to read about the new
   library features, but not try them until I find a possible use for
   them in my projects.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Update:&lt;/strong&gt; [2010-03] &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Downloads"&gt;Flex 4 is out&lt;/a&gt;, and includes &lt;a href="http://help.adobe.com/en_US/Flex/4.0/UsingSDK/"&gt;updated documentation&lt;/a&gt;. Like Flex 3, it targets Flash 10 but can also be used for earlier versions of Flash.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-523180181005764904?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/523180181005764904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=523180181005764904' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/523180181005764904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/523180181005764904'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/06/switching-to-flash-10.html' title='Switching to Flash 10'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-1926752602905624110</id><published>2009-06-08T16:00:00.000-07:00</published><updated>2009-06-08T16:00:04.265-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Road representation</title><content type='html'>&lt;p&gt;Playing Transport Tycoon, I've recently been setting up multimodal
   transport, where a bus will transport passengers from the bus stop in
   the middle of town to the train station outside of town (because once
   the towns in Transport Tycoon get big, it's hard to buy up enough land
   to build a train station or airport). The trains then take people to
   the nearby airport, which is even farther away from town for noise and
   space reasons. It would be fun to &lt;a href="http://simblob.blogspot.com/2009/05/transport-tycoon-modular-airports.html"&gt;design those airports
yourself&lt;/a&gt;,
   but Transport Tycoon gives you only a few rectangular predesigned
   airports.
&lt;/p&gt;
&lt;p&gt;The real trouble with playing Transport Tycoon is that it makes me
   want to write &lt;a href="http://simblob.blogspot.com/2006/02/rough-sketch-for-transportation-game.html"&gt;a transportation
game&lt;/a&gt;. I'm
   too busy to work on a full game right now, but I want to experiment
   with small pieces of games. I thought it'd be fun to design container
   ports that mix truck, train, and ship traffic. While trying to break
   that down into smaller problems, I decided to work on roads:
   representing them, simulating vehicle movement, and drawing
   them. &lt;a href="http://wildshadow.com/"&gt;Someone&lt;/a&gt; asked me: why use grids?  I
   love grids. &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;I think a lot about
grids&lt;/a&gt;. Even
   when I used &lt;a href="http://theory.stanford.edu/~amitp/game-programming/road-applet/roads.html"&gt;splines for
roads&lt;/a&gt;,
   the endpoints were on grid edges.  I recently updated &lt;a href="http://theory.stanford.edu/~amitp/GameProgramming/MapRepresentations.html"&gt;my A* pages
about non-grid
maps&lt;/a&gt;,
   and it seems like this project would be a good fit for a non-grid representation.
&lt;/p&gt;
&lt;p&gt;As I mentioned in the &lt;a href="http://simblob.blogspot.com/2009/05/throwing-away-code.html"&gt;last
post&lt;/a&gt;,
   I'm trying things quickly and am happy to throw them away if they
   don't work out.  I'm now on the fourth design, which uses a two-level
   graph structure.  The first graph is used by the player to edit
   the world. You'll place nodes and then connect them with edges. The
   second graph is used by pathfinding for vehicles to move along
   lanes. Each connection point generates one node per
   lane. Intersections export edges corresponding to all the ways a truck
   can go straight or turn, and roads export edges for going straight and
   for changing lanes.  The rough plan is to have three kinds of objects:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;“Anchor” objects like intersections and truck stops export connection points. The anchors act like nodes in the first graph and generate edges in the second graph. For example, a 4-way intersection will export 4 connection points.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Connection points have a position, orientation, and lane configuration. They don't show up in the first graph but generate nodes in the second graph. The lane configuration is the number of lanes in each direction. For example, a connection point might specify 2 lanes going one way and 1 lane going the other way.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Roads are attached to existing connection points and can follow a spline curve. Roads do not export their own connection points, but only can attach to anchor objects. They act as edges in the first graph and generate edges in the second graph.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Unlike the previous three designs, in which I quickly ran into trouble, this design has held up for a few weeks, so that's a good sign.  The subproblems are:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;How do I represent connection points? I decided to keep the position, orientation, and the number of lanes going into and coming out of the anchor object. It's a very simple struct and it'll be easy to change.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I represent intersections? I've limited myself to 4-way straight intersections (90 degree turns). Each side can have its own in/out lane configuration.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I draw intersections? For roads, there's a double yellow line in the center, a dashed white line between lanes going the same direction, and a solid white line on the side. There's a stop line where vehicles come to a stop. If there are right-only and left-only turn lanes, then there will be solid white lines separating those (not implemented yet). There may be arrows drawn to show which ways a vehicle can turn (not implemented yet). The size of the intersection itself is a rectangle as small as possible (not implemented yet).
&lt;/p&gt;
&lt;p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kV9ZnGnZL7M/SigC8ygQMsI/AAAAAAAAA28/I-BAOU3b7nI/s800/road%20intersection.png"&gt;&lt;img style="max-width:100%" src="http://lh4.ggpht.com/_kV9ZnGnZL7M/SigC8ygQMsI/AAAAAAAAA28/I-BAOU3b7nI/s800/road%20intersection.png" alt="Road intersections can have varying numbers of lanes"&gt;&lt;/a&gt;&lt;br /&gt;(Try &lt;a href="http://wiki.github.com/amitp/containerport/intersections"&gt;the demo&lt;/a&gt;!)&lt;/p&gt;
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I represent roads? I'd normally say cubic splines. However, since Flash supports drawing quadratic Bezier curves, it'd be nice if I could draw the roads using Flash instead of implementing my own curve rendering, so I'm going to use a spline with quadratic Beziers. There are &lt;a href="http://timotheegroleau.com/Flash/articles/cubic_bezier_in_flash.htm"&gt;ways to approximate cubics with quadratics&lt;/a&gt; but I'll see how far I get with quadratics alone. The lane configuration at the ends of the roads is determine by the anchor points, and the road handles the change in configuration. It might even be useful to have a lane configuration at each spline handle.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I draw roads? The roads again have the same yellow and white stripes as in intersections. However, this is where I ran into some trouble. I want the lane stripes to be parallel.  This is done by taking the original curve and constructing an “offset curve”. Unfortunately, &lt;a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve"&gt;offsets of Bezier curves are not Bezier&lt;/a&gt;!
&lt;/p&gt;
&lt;p&gt;This could be a major problem. The more I dug into this problem, the more papers I found. It turns out that it affects various industries use Bezier curves (not only quadratic) for representing curves, and they use approximations for offset curves.  I found papers mentioning circular arcs, Pythagorean hodograph curves, &lt;a href="http://www.kms.or.kr/include/journal/downloadPdf.asp?articleuid=%7BB2ACEFC5-3DFD-420D-BF4D-C9F77200F833%7D"&gt;Hausdorff distance&lt;/a&gt;, and a few other things, but in the end I decided that what mattered was not whether the curve is exactly correct but whether it looks reasonable.
&lt;/p&gt;
&lt;p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kV9ZnGnZL7M/SigC83m-wEI/AAAAAAAAA20/KdWJCB8mnbQ/s800/road%20bezier.png"&gt;&lt;img style="max-width:100%" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SigC83m-wEI/AAAAAAAAA20/KdWJCB8mnbQ/s800/road%20bezier.png" alt="Road drawn using Bezier curves"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;I drew the Bezier curve and the constructed somewhat-parallel Bezier curves, and it turns out it looks okay at low curvatures but not high curvatures:
&lt;/p&gt;
&lt;p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_kV9ZnGnZL7M/SigC88moSGI/AAAAAAAAA24/X1kSihTw0js/s800/road%20bezier%20offset%20bad.png"&gt;&lt;img style="max-width:100%" src="http://lh4.ggpht.com/_kV9ZnGnZL7M/SigC88moSGI/AAAAAAAAA24/X1kSihTw0js/s800/road%20bezier%20offset%20bad.png" alt="Bezier offset curves can be a problem"&gt;&lt;/a&gt;&lt;br /&gt;(Try &lt;a href="http://wiki.github.com/amitp/containerport/roads"&gt;this demo&lt;/a&gt;.)&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;I think it'll be reasonable to restrict the curvature of the road, and then I can use Flash for drawing the roads and lane markers.  A new problem arose: although Flash 10 allows bitmap line drawing (this is how I draw the “dashed” lane divider lines), the bitmap orientation is fixed and does not curve as the line does. I'm not yet sure how much of a problem this will be.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I move along roads? With Bezier curves, the &lt;a href="http://www.algorithmist.net/beziereasing.html"&gt;movement isn't uniform&lt;/a&gt;; I need to &lt;a href="http://www.cs.uiowa.edu/~kearney/pubs/CurvesAndSurfacesArcLength.pdf"&gt;adjust for arc length&lt;/a&gt;. Most likely I'll turn each lane path into a series of points, and then move linearly between them. If that doesn't look good then I'll try something else.
&lt;/p&gt;
&lt;p&gt;One thing I'm considering is using circular arcs instead of Bezier curves.  Arcs are fairly easy to understand and have simple movement. Offset curves from circular arcs are also arcs. Also, arcs are commonly used in real roads. Arcs can be &lt;a href="http://www.spaceroots.org/documents/ellipse/elliptical-arc.pdf"&gt;approximated with Bezier curves&lt;/a&gt;.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;How do I handle collisions? Open Transport Tycoon's “path based signals” have vehicles reserve the path ahead of them. Grids make this easier because you can reserve grid spaces (although OTTD is a little smarter than this and can allocate half-grids). Without grids, I could either precompute all intersecting road segments and mark them all occupied whenever one of them is reserved, or I could use polygon intersection to watch for vehicles colliding. The first approach uses planning; the second is purely reactive.  I think a reactive system would lead to traffic jams.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Road representation turns out to be a fun problem. As the code stabilizes, I'm pushing it out to &lt;a href="http://github.com/amitp/containerport/tree/master"&gt;github&lt;/a&gt; and I'll put demos into the &lt;a href="http://wiki.github.com/amitp/containerport"&gt;wiki&lt;/a&gt;. It's all under the MIT license so feel free to use it for anything. My next step is to determine how the roads and anchors connect to each other. That problem may help me decide on Bezier curves vs. arcs.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-1926752602905624110?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/1926752602905624110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=1926752602905624110' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1926752602905624110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1926752602905624110'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/06/road-representation.html' title='Road representation'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_kV9ZnGnZL7M/SigC8ygQMsI/AAAAAAAAA28/I-BAOU3b7nI/s72-c/road%20intersection.png' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5714692101590080552</id><published>2009-05-31T16:35:00.000-07:00</published><updated>2009-05-31T20:20:32.440-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Following multiple paths in RPGs</title><content type='html'>&lt;p&gt;Last year at GDC I was talking to the &lt;a href="http://wildshadow.com/"&gt;Wild Shadow
Studios&lt;/a&gt; guys about traditional classes in
   fantasy RPGs (ranger, wizard, barbarian, cleric, etc.). Some of our
   complaints about classes in many multiplayer RPGs:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;Classes come with roles such as “tank”, “healer”, “ranged”,
   “melee”, “crowd control”, etc. If you want to join a group that
   needs a tank, but your class is about melee damage, you can't join
   the group.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;The beginning of the game is a bad time to choose a class, which
   impacts you for the entire game. It's too early in the game to know
   what style of play you might like or what kind of roles are
   needed/useful. By the time you can make this decision it's too late;
   you've already invested lots of time into the game. Either you throw
   all that away or you keep playing the class that's not best for you.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Every class's play style can be considered “content”, and by
   choosing just one the player is missing out on other styles of
   play. As a game developer, if you have 5 classes, and players only
   play one of these on average, you're spending a lot of money on
   “content” that most players won't see, especially if armor/weapons
   are written for just a few classes in mind.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In Diablo 2, you picked a class but you could also customize that
   class by choosing skills as you level up. For example, Barbarians
   could choose skills such as Taunt or Double Swing. The skills had
   level requirements and prerequisites; for example, Double Swing was
   only available if you already had Bash. The trees were divided into
   three specialties per class; each of these effectively acts as a
   sub-class, so you had 15 styles of play instead of just 5 classes. The
   skills available to you were fairly limited at the beginning of the
   game, so you're not overwhelmed, and you don't have to make your
   choices at the beginning. This partially addresses complaint #2.
&lt;/p&gt;
&lt;p&gt;In Guild Wars and Titan Quest, you get to pick two
   classes. Multiclassing has been around since the D&amp;amp;D days, but these
   two games makes two classes the default and one class an
   option. Multiple classes can help with complaint #1, since everyone
   has two roles. It also helps with complaint #3, by adding lots of
   variety without having to create new content around it.
&lt;/p&gt;
&lt;p&gt;In Silverfall, World of Warcraft, and Titan Quest, I can change my
   skills later in the game, but not my class. WoW also has hybrid
   classes such as druid and shaman that can perform multiple roles. This
   also helps slightly with complaint #1, but it's quite a
   hassle. (Recently, WoW introduced “dual specs”, which help quite a bit
   by letting you set up two sets of skills that can be swapped with one
   button.)  Being able to change my skills later &lt;em&gt;greatly&lt;/em&gt; increased my
   desire to experiment. In Diablo 2, I would pick skills based on the
   recommendations of others. Decisions you can't change are more likely
   to be conservative. But in WoW, I am much more willing to try out new
   things, because I can undo them.

&lt;/p&gt;
&lt;p&gt;In Dungeon Siege II, there are skill trees but no classes. You
   essentially define your class by choosing skills along the way, but
   you don't have to decide anything at the beginning of the game. Titan
   Quest also delays the decision-making of your first and second
   classes. Either approach addresses complaint #2.
&lt;/p&gt;
&lt;p&gt;Another way to address all three complaints is to have more than one
   character, each one trying out a different class and play style.  But
   when playing these characters, you start over from scratch.
&lt;/p&gt;
&lt;p&gt;What I'd like is (a) delaying decisions about classes/skills, and (b)
   allowing trying out other choices after I'm “finished” with my current
   class.  So here's the idea: as you progress in the game, you are given
   choices of specialties. If you later master multiple specialties, you
   can become a generalist. Here's a diagram:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kV9ZnGnZL7M/SiMKXrf8xHI/AAAAAAAAA2w/A13IAm2Irec/s800/class-tree.png"&gt;&lt;img style="max-width:100%" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SiMKXrf8xHI/AAAAAAAAA2w/A13IAm2Irec/s800/class-tree.png" alt="class diagram showing specialization followed by generalization" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;!-- DOT diagram

digraph {

  node [fontname="Helvetica", style="filled", color="#cccccc"];
  edge [color="#888888"];

  1 -&gt; 2;
  1 -&gt; 3;
  2 -&gt; 4;
  2 -&gt; 5;
  3 -&gt; 6;
  3 -&gt; 7;
  4 -&gt; 8; 4 -&gt; 9;
  5 -&gt; 10; 5 -&gt; 11;
  6 -&gt; 12; 6 -&gt; 13;
  7 -&gt; 14; 7 -&gt; 15;
  8 -&gt; 16; 9 -&gt; 16;
  10 -&gt; 17; 11 -&gt; 17;
  12 -&gt; 18; 13 -&gt; 18;
  14 -&gt; 19; 15 -&gt; 19;
  16 -&gt; 20; 17 -&gt; 20;
  18 -&gt; 21; 19 -&gt; 21;
  20 -&gt; 22; 21 -&gt; 22;

  1 [fillcolor="#ffffff", label="novice"];

  2 [fillcolor="#fdffe5", label="weaponry"];
  3 [fillcolor="#e6e5ff", label="magic"];

  4 [fillcolor="#ffe7d8", label="ranged"];
  5 [fillcolor="#ddffd8", label="melee"];
  6 [fillcolor="#d8f0ff", label="defensive"];
  7 [fillcolor="#fad8ff", label="offensive"];

  8 [fillcolor="#ffbfbf", label="bow"];
  9 [fillcolor="#ffefbf", label="dart"];
 10 [fillcolor="#dfffbf", label="sword"];
 11 [fillcolor="#bfffcf", label="axe"];
 12 [fillcolor="#bfffff", label="cold"];
 13 [fillcolor="#bfcfff", label="water"];
 14 [fillcolor="#dfbfff", label="shadow"];
 15 [fillcolor="#ffbfef", label="fire"];

 16 [fillcolor="#ffb07f", label="crossbow"];
 17 [fillcolor="#8eff7f", label="halberd"];
 18 [fillcolor="#7fceff", label="ice"];
 19 [fillcolor="#f07fff", label="death"];

 20 [fillcolor="#f6ff59", label="combat"];
 21 [fillcolor="#6d66ff", label="wizardry"];

 22 [fillcolor="#3fffff", label="master"];
}

--&gt;

&lt;p&gt;After you've played for a short time, you get to choose weaponry or
   magic. I choose weaponry. After playing more and leveling up with
   weaponry skills, I am able to specialize again, and I learn
   melee. After learning all the melee skills, I specialize in
   swords. After a few more levels, I am now fully specialized by mastering
   swords, and there's no more for me to learn. This is the
   equivalent of “level 80” in WoW.
&lt;/p&gt;
&lt;p&gt;At this point, it's time to try the branches I hadn't tried. This
   could either be by starting over with a new character at the novice
   level; or it could be by restoring a previous savegame where I was
   still at weaponry (playing a “clone” in a scifi setting), and choosing
   the ranged path instead; or it could be by using my current character
   to go back and learn ranged attacks. I don't know which of those
   approaches would be best for a game. In any case, I'm now trying out
   other play styles, just as with current RPGs.
&lt;/p&gt;
&lt;p&gt;Where this design differs is that there's something gained in-game by learning
   multiple specialties. This is the lower half of the diagram. If I
   master both the sword and axe, that unlocks the halberd.  If I master
   both ice and death magic, it unlocks wizardry skills. By playing and
   mastering all types of characters, I become a Master. 
&lt;/p&gt;
&lt;p&gt;An open question is how you handle the huge number of skills once
   you've pursued multiple paths. Titan Quest and Guild Wars limit your
   classes to two, so that it's not too bad. WoW lets you have two sets
   of skills, and you can swap back and forth at any time. Guild Wars
   further gives you a fixed number of skills at any time, and you can
   swap these out when you're in a major city. In a scifi setting, such
   as a robot or spaceship based game, you could assign the skills to the
   robot/vehicle you're in, and then jump into a different robot/vehicle
   to swap skills (Wild Shadow Studios is working on a &lt;a href="http://blog.wildshadow.com/wild_shadow_studios/2009/05/gametwo.html"&gt;tank-based
MMO&lt;/a&gt;

   that does this). Choosing sets of skills before you go into combat
   seems like a reasonable way to limit the complexity, and also
   encourage planning ahead.
&lt;/p&gt;
&lt;p&gt;This skill graph addresses complaint #2: you don't have to make
   permanent choices at all, and the choices you make come after you've
   been playing the game for a bit. It also addresses #3: there's a path
   for the player to experience all the “content” the developers
   create. It partially addresses #1, by allowing you to play different
   roles at different times. Novice players can follow a recommended path
   to specialize in just one “class”, whereas experienced players can
   experiment more and try out new combinations. I think it could be fun
   to play with such a system, but I'm not planning to write an RPG any
   time soon.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5714692101590080552?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5714692101590080552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5714692101590080552' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5714692101590080552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5714692101590080552'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/05/following-multiple-paths-in-rpgs.html' title='Following multiple paths in RPGs'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_kV9ZnGnZL7M/SiMKXrf8xHI/AAAAAAAAA2w/A13IAm2Irec/s72-c/class-tree.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3054286815827838685</id><published>2009-05-10T22:13:00.000-07:00</published><updated>2009-05-10T22:41:49.171-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Throwing away code</title><content type='html'>&lt;p&gt;
I've been trying to get better at throwing away code. I used to be a packrat. I saved every receipt, every bill, every check, every bank statement, every page of notes I took in class, every textbook, and so on. Eventually I started letting go of most of these things. Class notes were the hardest though. I had put so much effort into them; how I could throw them out?
&lt;/p&gt;
&lt;p&gt;
I realized that I was making the same mistake that I make with market prices. I expect prices to reflect the &lt;em&gt;cost&lt;/em&gt; of making the item. But in many cases, prices reflect what &lt;em&gt;it's worth to the buyer&lt;/em&gt;. In this case, I was saving my notes because they cost a lot to produce. But they don't have much value to me in terms of looking things up. I haven't used them in over ten years, and Wikipedia and other online sources are better references. So I finally threw away my class notes.
&lt;/p&gt;
&lt;p&gt;
I find that I have the same problem with code. It takes effort to write, so I feel like I should save it. But sometimes it's the wrong code or it's solving the wrong problem. There are times when the best thing to do is to throw it away.
&lt;/p&gt;
&lt;p&gt;
To make it easier to throw away code, I'm trying to reduce the cost of producing it, &lt;em&gt;especially&lt;/em&gt; when I'm less sure about how long I'll need it or whether it's the right way to go. This is not only helpful for me psychologically, but I think it's the right thing to do engineering-wise. Note that this is the opposite of the conventional wisdom — that you should put lots of effort up front into “doing things right”, because it'll pay off later.
&lt;/p&gt;
&lt;p&gt;
Keeping costs down recently paid off for me.
&lt;/p&gt;
&lt;p&gt;
While playing Transport Tycoon a few weeks ago, I was thinking about &lt;a href="http://simblob.blogspot.com/2009/05/transport-tycoon-modular-airports.html"&gt;modular airports&lt;/a&gt;, and how it related to my &lt;a href="http://simblob.blogspot.com/2007/01/transportation-mini-game-rough-design.html"&gt;transportation mini-game&lt;/a&gt; that's on indefinite hold. I'm not working on any games right now, but instead working on &lt;a href="http://simblob.blogspot.com/2008/12/game-component-radial-base-layout.html"&gt;little bits and pieces&lt;/a&gt; that might end up being part of a game. Or at the very least I'll learn a lot by working on these components. One of the open questions I've had when thinking about a transportation game is how I should represent roads and vehicles (or rails and trains).  I sketched some ideas on paper, and then decided on a representation of road segments:
&lt;/p&gt;
&lt;pre&gt;
  public class Path {
    public var id:int;
    public var next:int; // index

    // Positions are in world coordinates, not Flash coordinates
    public var beginPosition:Point;
    public var beginOrientation:Point;
    public var endPosition:Point;
    public var endOrientation:Point;

    public var length:Number;

    public function Path(id_:int) {
      id = id_;
    }
  }
&lt;/pre&gt;
&lt;p&gt;
I then set up some test segments and made vehicles go around on them:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://lh5.ggpht.com/_kV9ZnGnZL7M/SgehP6sK0XI/AAAAAAAAA00/9nCPmXYUHXo/s800/simple-roads.png"&gt;&lt;img style="max-width:100%" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SgehP6sK0XI/AAAAAAAAA00/9nCPmXYUHXo/s800/simple-roads.png"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I had convinced myself that inside an airport or container port, the vehicles could move around in loops, and that would be sufficient for a game. Even if I needed branching, I could change my &lt;code&gt;Path&lt;/code&gt; class from having a single next pointer to multiple next pointers.
&lt;/p&gt;
&lt;p&gt;
I was quite happy with the vehicle and road representation. I had a coordinate system that allowed vehicles to detect if someone's in front of them, and to slowly come to a stop before they collided. By using a loop I had eliminated the problem of start and end points.
&lt;/p&gt;
&lt;p&gt;
A few days later I tried sketching out what the player would do. It turned out that there wasn't much. I spent some time thinking about why Transport Tycoon's station management was interesting, and my prototype was not, and realized that what's interesting is &lt;em&gt;updating&lt;/em&gt; the station over time to deal with changes in the game world. If players spent most of their time on updates rather than initial design, the road shouldn't be a loop. It should support adding temporary routes, closing existing routes, demolishing routes, building new routes, and so on. &lt;em&gt;Those&lt;/em&gt; operations work better with a completely different representation of roads. And that meant I should throw away my representation and associated code (rendering, etc.).
&lt;/p&gt;
&lt;p&gt;
If you look at the class I wrote, it's trivial. Everything's public. There are no getters and setters, no methods, a trivial constructor, and no tests. I tried hard to follow &lt;a href="http://c2.com/cgi/wiki?YouArentGonnaNeedIt"&gt;YouArentGonnaNeedIt&lt;/a&gt; and &lt;a href="http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork"&gt;DoTheSimplestThingThatCouldPossiblyWork&lt;/a&gt;. Throwing it away is &lt;em&gt;easy&lt;/em&gt;, because there's so little work put into it. Having the old version saved in version control helps me feel okay with removing the code in the current version.
&lt;/p&gt;
&lt;p&gt;
Although I'm throwing away code, there are some ideas I'm keeping. I learned some things, and the first approach is what got me thinking about the new approach. The &lt;em&gt;process&lt;/em&gt; was valuable, even if the &lt;em&gt;code&lt;/em&gt; was not. And I've started working on the next approach, which I'll try to keep as simple as the first one. I still have a packrat instinct, but I'm working on conquering it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3054286815827838685?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3054286815827838685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3054286815827838685' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3054286815827838685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3054286815827838685'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/05/throwing-away-code.html' title='Throwing away code'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_kV9ZnGnZL7M/SgehP6sK0XI/AAAAAAAAA00/9nCPmXYUHXo/s72-c/simple-roads.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7088183630510606884</id><published>2009-05-04T00:11:00.000-07:00</published><updated>2009-05-04T00:11:34.495-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><title type='text'>Transport Tycoon: modular airports</title><content type='html'>&lt;p&gt;&lt;a href="http://simblob.blogspot.com/2007/11/transport-tycoon.html"&gt;I have been playing Transport Tycoon for a long
time&lt;/a&gt;. It's
   my all-time favorite game. &lt;a href="http://www.ttdpatch.net/"&gt;TTDPatch&lt;/a&gt; is a
   very impressive set of patches for the game, adding lots of new
   features that seem like they would be impossible to implement in a
   patch, especially by authors who don't have access to the source
   code. &lt;a href="http://www.openttd.org/en/"&gt;Open Transport Tycoon&lt;/a&gt; is an open
   source port/recreation of the game, and it's what I've been playing
   lately.
&lt;/p&gt;
&lt;p&gt;In Transport Tycoon your goal is to build a transportation empire
   using buses, trucks, trains, airplanes, and ships. The part I find the
   most fun is laying out tracks, railroad stations, and train signals. I
   think most of the players spend most of their time on railroads for
   this reason. I think I would enjoy the airplane and ship parts of the
   game more if I had some control over layout. All you can build right
   now is &lt;a href="http://wiki.openttd.org/Airports"&gt;6 predefined rectangular
airports&lt;/a&gt; and 1 ship dock.
&lt;/p&gt;
&lt;p&gt;For several years on the Open Transport Tycoon forums, there's been
   talk of “modular” airports that would allow players to place hangars,
   runways, taxiways, and gates to build their own airport. However,
   airports are implemented with finite state machines that carefully
   manage multiple airplanes in holding patterns, landing, taking off,
   taxiing, going to hangars, and stopping at gates. Richk67 has &lt;a href="http://www.tt-forums.net/viewtopic.php?f=33&amp;amp;t=33163"&gt;created
an impressive
patch&lt;/a&gt; for custom
   non-rectangular airports. However his experience has been that the
   finite state machines are just too complex for players, and his patch
   is instead aimed at people making addons. Pikka has an &lt;a href="http://users.tt-forums.net/pikka/wiki/index.php?title=Newgrf_Airports_Documentation#Example_Airports"&gt;alternate
proposal&lt;/a&gt;,
   but take a look at the example state machine code for the simple
   airport. That's way too complex to make players deal with. There have
   been others who have argued that it should be possible to let players
   do this, if the GUI was good enough. However, Richk67 actually wrote
   some code and implemented custom airports, whereas most of the posters
   are just talking about proposals or ideas, so I generally believe him
   when he says that the finite state machines are too complex for most
   players.
&lt;/p&gt;
&lt;p&gt;My hope however was that there would be a completely different
   approach to airports that wouldn't involve the complex finite state
   machines. Playing with &lt;a href="http://wiki.openttd.org/Path_Based_Signaling"&gt;path based
signals&lt;/a&gt;, a new feature
   in OpenTTD 0.7.0, has made me more optimistic. With the signals in the
   original Transport Tycoon, a train made a decision when it reached a
   junction with signals. The third party patches added new kinds of
   signals, including allowing complex logic in TTDPatch. Path-based
   signals work quite differently. Trains reserve tracks ahead of them
   and only proceed if they can make a reservation. Can we apply the same
   idea to airports? Instead of following a fixed state machine, we might
   be able to reserve space ahead of the airplane (landing flight space,
   takeoff flight space, runways, taxiways). I had only just started
   thinking about this problem when I came across &lt;a href="http://www.tt-forums.net/viewtopic.php?f=32&amp;amp;t=38709"&gt;Dimme's
demo&lt;/a&gt; of a
   proposed player-created airport system using airplanes reserving space
   they want to use. In the demo (a Java app), you can place gate,
   runway, taxiway, and other tiles to build an airport, and then run a
   simulation to see how the airplanes use it. It's quite impressive!
   (Note: I couldn't get the &lt;code&gt;jar&lt;/code&gt; file to run on the Mac so I had to
   recompile it myself, but it ran fine.)
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_kV9ZnGnZL7M/Sf6RfzgQ48I/AAAAAAAAA0U/R4i2wkATWq8/s800/Airport%20editor.png"&gt;&lt;img style="max-width:100%" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/Sf6RfzgQ48I/AAAAAAAAA0U/R4i2wkATWq8/s800/Airport%20editor.png" alt="Dimme's demo screenshot"/&gt;&lt;/a&gt;&lt;br /&gt; A station I made with Dimme's demo
&lt;/p&gt;
&lt;p&gt;Dimme's demo shows that there's a different way to build airports that
   may not lead to the same complexity as the finite state
   machines. MarkyParky, who works with airports in real life, has &lt;a href="http://www.tt-forums.net/viewtopic.php?p=733954#p733954"&gt;good
things to say about Dimme's
demo&lt;/a&gt;, but
   &lt;a href="http://www.tt-forums.net/viewtopic.php?p=733976#p733976"&gt;also talks about holding
patterns&lt;/a&gt;,
   which turn out to be more complicated than I imagined. I don't think
   that realistic holding patterns are necessary but it's something to
   think about. In any case, I don't think any of the discussions are
   going to go anywhere. Richk67's patch is the only code I saw, and as
   far as I can tell, the main developers have rejected his patch. Dimme
   demonstrated an alternate approach but there's no proposal for how to
   make it work within the OpenTTD code.
&lt;/p&gt;
&lt;p&gt;Dimme's demo is good. It's simple to use, it demonstrates the idea,
   and it lets you actually try building an airport to see how it
   works. After playing with it, I decided I wouldn't build an airport
   building demo. I think my ideas aren't different enough to make it
   worth it. However, his demo reminded me that I should be building more
   demos of ideas I want to explore. Coming up with ideas doesn't teach
   me as much as trying them out.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7088183630510606884?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7088183630510606884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7088183630510606884' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7088183630510606884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7088183630510606884'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/05/transport-tycoon-modular-airports.html' title='Transport Tycoon: modular airports'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_kV9ZnGnZL7M/Sf6RfzgQ48I/AAAAAAAAA0U/R4i2wkATWq8/s72-c/Airport%20editor.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5099558235988439271</id><published>2009-04-13T19:26:00.000-07:00</published><updated>2009-04-13T22:14:12.260-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><title type='text'>Animating stick figures</title><content type='html'>&lt;p&gt;
For about 15 years now I've wanted to do something with stick
figures. I never knew &lt;em&gt;what&lt;/em&gt;. I just wanted to try animating them. The
games I like tend to be isometric or top-down views; I generally don't
like first person or side views. As a result, stick figure animation
just never seemed useful enough to put into one of my games.
&lt;/p&gt;

&lt;p&gt;
While reading Scott McCloud's books about comics a few years ago, I
had an idea blending comic books and games, and it just happens to be
a good fit for stick figure animation.  I'm not sure I want to pursue
it, but since I had spent so much time on the spaceship physics and
editor, I thought it'd be a good break for me to take a break and take
a look at stick figure animation. If it turns out to be fun I might
explore the comic book idea a bit more. 
&lt;/p&gt;

&lt;p&gt; The other thing that I've been wanting to explore is the ninja
side of the pirates vs. ninjas theme. Sure, we have &lt;a
href="http://askaninja.com/"&gt;Ask a Ninja&lt;/a&gt;, but overall I think the
pirates have gotten far too much attention. There are several
pirate-themed games, like Sid Meier's Pirates, Puzzle Pirates, and
Tropico 2 Pirate Cove, but not so many for ninjas. &lt;a
href="http://www.talklikeapirate.com/"&gt;Talk Like a Pirate Day&lt;/a&gt; gets
plenty of attention but the equivalent for ninjas just doesn't
compare. Only the Somali pirate attacks are hurting the pirate
image. So if I write a stick figure animation game, the protagonist
will be a ninja fighting the evil pirates.&lt;/p&gt;

&lt;p&gt; How am I going to make my 2D ninja stick figure move? There are
are lots of approaches to character animation: forward kinematics,
inverse kinematics, physical simulation, “ragdoll” physics, motion
capture, etc.  My goal was to make something simple and reasonable
without putting in much artwork (motion capture or hand-drawn
animation). My hope was that a 2D stick figure would take much less
effort than the full 3D motion systems. &lt;/p&gt;

&lt;p&gt; I wanted to try the simplest approach first, using basic geometry
to move the legs. The hip and knee angles tell me where the ankle will
end up. If I know where I want the ankle to be, I should be able to
find the hip and knee angles. I tried approaching it as a gradient
function, using hill-climbing to reach the solution, but it turns out
this is overkill if you only have two angles. The femur and tibia
length are known, and I know the distance between the hip and my
desired ankle position. That means we know the three sides of the
triangle, and can use the &lt;a
href="http://en.wikipedia.org/wiki/Law_of_cosines"&gt;law of cosines&lt;/a&gt;
to determine the angles. Simple. Ankles and wrists work out pretty
nicely. &lt;/p&gt;

&lt;p&gt; The next step was to make the figure take a step (pun intended,
sorry!). I looked at some animator pages about the &lt;a
href="http://www.idleworm.com/how/anm/02w/walk1.shtml"&gt;walk cycle&lt;/a&gt;
I also read &lt;a href="http://www.cs.ubc.ca/~van/papers/"&gt;lots of papers
about walking mechanics&lt;/a&gt;, including some about automatically
“learning” how to walk.  Along the way I discovered something cool: &lt;a
href="http://www-personal.umich.edu/~shc/pdw.html"&gt;passive walking
dynamics&lt;/a&gt; (see animation &lt;a
href="http://www-personal.umich.edu/~artkuo/Passive_Walk/passive_walking.html"&gt;here&lt;/a&gt;),
which treats walking as an inverted pendulum (your body over the
supporting leg) and a normal pendulum (your free leg swinging
freely). It seems to be a pretty good approximation of how people
walk.  &lt;/p&gt;

&lt;p&gt; I decided the simplest thing would be to make the target ankle
position follow a circle, as if you were on a bicycle, and then have
the ground prevent your foot from going down. This actually looked
reasonable, but the “liftoff” and “landing” of the foot didn't look
right. To make them look better, I added transitions (see &lt;a
href="http://www.awn.com/qas/60.html"&gt;this page&lt;/a&gt;) that used the toe
as a pivot point (for liftoff) and the heel as a pivot point (for
landing). This definitely looked better, but the liftoff and landing
have the ankle moving in circular arcs, and these don't smoothly
transition into the overall circular motion. I improved it a bit more
by making the ankle follow a spline that matched the arcs. &lt;/p&gt;

&lt;p&gt;I was pretty happy with the walking animation, but several friends
reminded me that in a ninja game, you're not going to spend much time
seeing the ninja &lt;em&gt;walk&lt;/em&gt;. The ninja will &lt;em&gt;run, sneak, jump,
kick, punch, throw stars, duck, swing, hide, and do flips&lt;/em&gt;, but
walking? How boring. So once again I realized that I had been focusing
on the wrong problem. The second thing was that my test app had a
giant ninja, but in the game it'd look tiny, so all the little details
like the flexing foot, the bounce in his step, or the liftoff and
landing (which would be only a pixel high) really don't matter. [Edit 2008-05-13: changed “pirate” to “ninja”; thanks Anonymous for pointing out my error.]
&lt;/p&gt;

&lt;p&gt;
&lt;img src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SePwqVIpzHI/AAAAAAAAAzc/pL67-bfidew/s800/ninja-walker.png" alt="Ninja walker test application" /&gt;
&lt;/p&gt;

&lt;p&gt; I'm not sure where I want to go with this. The walking research
papers were cool, but I didn't find research papers about
gravity-defying ninja backflips. My gut tells me that the ninja
doesn't obey the laws of physics, and thus I should stick to the
geometrical approach instead of using a physics engine. &lt;a
href="http://box2dflash.sourceforge.net/"&gt;Box2D&lt;/a&gt; looks pretty neat,
and I'm sure I can use physics for other things in the game. But I
need to first figure out how I'm going to implement ninja moves. Do I
want to procedurally generate them somehow, or do I want to hand-pick
the key frames? It'd be &lt;em&gt;cool&lt;/em&gt; to generate them in a way that
could take into account everything in the scene. For example, a jump
kick should be able to jump on the box before jumping for the
kick. But I suspect that's a lot more work than I want to tackle right
now, and unless it's a key part of the game (if I end up writing a
game), it's just not that important.
&lt;/p&gt;

&lt;p&gt; That brings up the question: what is the goal here? Am I doing
this to satisfy my long-time dream of animating stick figures, or
should I try to write a little game that can show off the comic book
idea, or do I really want to write a game?
&lt;/p&gt;

&lt;p&gt;
I don't know yet. So that leaves me at: I &lt;em&gt;still&lt;/em&gt; want to do something with animated stick figures, and I &lt;em&gt;still&lt;/em&gt; don't know what. But if I ever figure it out, I have now learned some things that might come in handy.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5099558235988439271?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5099558235988439271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5099558235988439271' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5099558235988439271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5099558235988439271'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/04/animating-stick-figures.html' title='Animating stick figures'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_kV9ZnGnZL7M/SePwqVIpzHI/AAAAAAAAAzc/pL67-bfidew/s72-c/ninja-walker.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6141530980154236239</id><published>2009-03-28T22:19:00.000-07:00</published><updated>2009-03-28T22:36:40.657-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Flash 9 triangle gradients</title><content type='html'>&lt;p&gt;
Flash 9 offers the &lt;a href="http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;amp;file=00001897.html"&gt;&lt;code&gt;beginGradientFill()&lt;/code&gt;&lt;/a&gt; method for drawing N-color 1D linear and radial gradients. However, I couldn't find a way to draw 3-color 2D gradients as seen in &lt;a href="http://en.wikibooks.org/wiki/OpenGL_Programming/Basics/Color#Giving_Individual_Vertices_Different_Colors"&gt;OpenGL&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I could compute the gradient myself and just set pixel values in a &lt;code&gt;BitmapData&lt;/code&gt;, and then render those pixels to make my triangle. But that's no fun. It turns out &lt;code&gt;BitmapData&lt;/code&gt; objects support lots of interesting operations like add, multiply, subtract, and even a limited form of lookup. 
&lt;/p&gt;
&lt;p&gt;
By incredible coincidence, triangles have &lt;strong&gt;three&lt;/strong&gt; vertices and colors have &lt;strong&gt;three&lt;/strong&gt; components. So you can use colors to store information about vertices. (Note that in the 3D DirectX/OpenGL shader world we do something similar by storing normal maps in color channels.) Here's what I came up with:
&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Make a triangle bitmap where the red, green, and blue components of the color correspond to the barycentric coordinates of that point in the triangle, scaled to 0–255 instead of 0–1. I only have to do this once.&lt;/li&gt;
  &lt;li&gt;Make a gradient array for the three colors I want at the vertices. The gradient array is 256 elements and it's merely the red, green, and blue values scaled down. At position &lt;em&gt;i&lt;/em&gt; I'll store the color scaled to i/255 brightness.&lt;/li&gt;
  &lt;li&gt;Use &lt;a href="http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;amp;file=00001414.html"&gt;&lt;code&gt;BitmapData.paletteMap()&lt;/code&gt;&lt;/a&gt; to map the red, green, and blue components to the scaled colors in my three gradient arrays.  The &lt;code&gt;paletteMap()&lt;/code&gt; function adds the color values in those arrays to produce the final color.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
This is what the triangle bitmap looks like. The red, green, and blue channels represent the barycentric coordinates:
&lt;/p&gt;
&lt;img style="max-width:100%" src="http://lh3.ggpht.com/_kV9ZnGnZL7M/Sc7u9-RN13I/AAAAAAAAAxc/P8LSFBvKxK0/s800/gradient-map.png" /&gt;
&lt;p&gt;
The way this technique works is that &lt;code&gt;paletteMap()&lt;/code&gt; calculates the output color at each pixel to be &lt;code&gt;array1[red] + array2[green] + array3[blue]&lt;/code&gt;, where the indices are the color components from the input array. In the input array, red+blue+green equals 255, and the three arrays have the color scaled up to 255. So this gives me &lt;strong&gt;interpolation between any three colors&lt;/strong&gt;. For example, if red is 20, green is 80, and blue is 155, then the final color is array1[20] + array2[80] + array3[155] = (20/255*color1) + (80/255*color2) + (155/255*color3), which is the interpolation we want. Here's an example of what happens when we apply this to a triangle with green, purple, and yellow vertices:
&lt;/p&gt;
&lt;img style="max-width:100%" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/Sc7uH3qH_NI/AAAAAAAAAxE/0q2Dh1JdKbI/s800/gradient-test.png" /&gt;
&lt;p&gt;
I should also note that &lt;code&gt;paletteMap()&lt;/code&gt; can take four arrays instead of three; the fourth is alpha. I tried building an Alpha+RGB quad bitmap for mapping, and then using four colors with that. Unfortunately I couldn't get it to work. I think &lt;code&gt;paletteMap()&lt;/code&gt; uses alpha both for the map and for the blending (this is undocumented). Or maybe it's doing something else I don't understand. In any case I gave up on it.
&lt;/p&gt;
&lt;p&gt;
The big downside of this technique is that you have to fill those arrays each time. In general, this could get expensive. If the triangles are small, it'd be faster to directly compute the interpolation per pixel (the "not fun" technique I mentioned at the top). However, in some situations you only need a few colors, and can precompute those gradient arrays. A friend of mine wants to use this for lighting calculations, and for white lights you can precompute all 255 light levels. I was hoping to use gradients to render a map (like the one in the &lt;a href="http://simblob.blogspot.com/2009/03/game-component-spaceship-editor-part-4.html"&gt;spaceship editor demo&lt;/a&gt;), and if my maps contain only a few terrain types (grass, sand, etc.), I can precompute all my gradient arrays. I can use this technique to compute a color gradient bitmap, and then mix with those with my terrain textures using the standard blend operations.
&lt;/p&gt;
&lt;p&gt;
Eventually I'll be using Flash 10, and that'll open up new techniques, especially with shaders. But for now, I'm using Flash 9 for my site, and I'll try to push &lt;code&gt;BitmapData&lt;/code&gt; to do some things it probably wasn't meant to do.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6141530980154236239?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6141530980154236239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6141530980154236239' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6141530980154236239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6141530980154236239'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/03/flash-9-triangle-gradients.html' title='Flash 9 triangle gradients'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_kV9ZnGnZL7M/Sc7u9-RN13I/AAAAAAAAAxc/P8LSFBvKxK0/s72-c/gradient-map.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-8818639201392620884</id><published>2009-03-22T00:39:00.000-07:00</published><updated>2009-12-05T18:26:43.287-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Game Component: Spaceship editor, part 4</title><content type='html'>&lt;p&gt;Last year I decided that I just don't have the time and energy to work
   on a full game, and instead I should work on quick prototypes
   instead. I had planned to try an idea every few weeks. The &lt;a href="http://simblob.blogspot.com/2008/12/game-component-radial-base-layout.html"&gt;space
station
generator&lt;/a&gt;
   was one of these; the &lt;a href="http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-1.html"&gt;spaceship
editor&lt;/a&gt;
   was another.  Spaceship physics turned out to be really interesting
   and I kept working on it. It's been months now.  I have lots of other
   things I want to try, so I need to wrap this up, even if there's more I could do.
&lt;/p&gt;
&lt;p&gt;In the &lt;a href="http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-3.html"&gt;last
post&lt;/a&gt;
   I talked about the physics. The final step was to figure out whether
   there were interesting tradeoffs that a player could make when
   designing a ship. I needed a spaceship editor.
&lt;/p&gt;
&lt;img align=right src="http://lh4.ggpht.com/_kV9ZnGnZL7M/ScXONnDA1jI/AAAAAAAAAwA/leck6l_VEfM/s288/mouse-drag-state-diagram.png" alt="State diagram for mouse dragging"/&gt;
&lt;p&gt;I made a circle that could be dragged around with Flash's built-in
   draggable object feature, but I switched to handling the mouse events
   myself, so that I could add "snap to angle" and other constraints. It
   wasn't long after having a draggable circle that I made a circle for
   each thruster. And then two, one for the head and one for the tail. I
   also wanted the thruster to move as a whole if you dragged the base,
   but only the tip to move if you dragged the end. I overlaid these on a
   large version of the ship to make a ship editor. Now I could start
   answering the key question: are there interesting design choices?
&lt;/p&gt;
&lt;p&gt;After playing around with lots of configurations my answer was
   &lt;strong&gt;no&lt;/strong&gt;.  It's always better to put the forward thrusters
   near the wingtips. You don't lose any forward thrust, and you gain a
   great deal of rotational speed. The other thrusters were less of an
   issue, because they were used for less common motions.
&lt;/p&gt;
&lt;p&gt;To make this interesting I need some disadvantage of putting forward
   thrusters at the tips.  One thing I considered was that thrusters at
   the edges of your ship are more vulnerable to damage. However, I don't
   actually have a game here, so that's not something I can easily
   test. So I turned to the other idea: thrusters require support that
   have mass. Putting a thruster far from the center requires more
   massive supports, which slow you down.  I started with mass and moment
   of inertia calculations from physics, and then used tuning and
   experimentation to come up with something that felt reasonable. The
   main tradeoff I focused on is between rotational and forward
   acceleration, when both are from the same forward thrusters. If you
   move the thrusters near the wingtips, you get lots of rotation, but
   you need a lot of mass for the structural supports, and that slows
   your forward acceleration.  This plot shows acceleration versus
   thruster distance from the center:
&lt;/p&gt;
&lt;p&gt;&lt;img style="width:100%" src="http://lh4.ggpht.com/_kV9ZnGnZL7M/ScXULLSOckI/AAAAAAAAAwI/RJZdpVHiNHQ/s800/ship-physics-tradeoffs.png" alt="Tradeoff between forward and rotational acceleration"/&gt;
&lt;/p&gt;
&lt;p&gt;It shows that at least for the forward thrusters, there's a nice
   tradeoff between rotational and forward acceleration, and you can't
   get unlimited rotational power because the supports become too
   massive.  There are lots of other things I could look at, but I think
   some tradeoffs depend on the game (for example, they may be completely
   different if the ship is in an atmosphere than if it were in space),
   and I'm not writing a game right now. 
&lt;/p&gt;
&lt;p&gt;I eventually recognized that I could keep working on this for a long
   time, but &lt;strong&gt;I need to move on and explore other topics&lt;/strong&gt;. I've mostly
   answered the question I set out to answer: if you let the player
   design the spaceship, are there interesting tradeoffs arising from the
   physics? I think the answer is yes, but probably not as many
   interesting tradeoffs as Spore's approach would allow. In addition,
   things weren't automatically interesting; I had to design a tradeoff
   and then tune the physics to make that tradeoff show up, and I had to
   be careful to avoid overpowered ships. That was unsatisfying. In a
   real game I imagine I'd have to manually design lots of tradeoffs for
   different game levels or areas of the world, and it'd be quite tough
   to test all the combinations. And even if I could do that, controlling
   sliders in a continuous tradeoff space seems less fun than picking
   from some really interesting manually designed items in Spore or
   &lt;a href="http://sc2.sourceforge.net/screenshots/scale_triscan.php"&gt;Ur-Quan
Masters&lt;/a&gt;. So
   &lt;strong&gt;yes&lt;/strong&gt;, I was able to make what I set out to make, and it was fun to play
   with, but probably would be a lot less work and more fun to give
   people a few interesting choices.
&lt;/p&gt;
&lt;h2&gt;The Demo&lt;/h2&gt;

&lt;p&gt;Of course after all that I should let you try designing your own ships
   and see what you think. Instructions:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;Press &lt;kbd&gt;T&lt;/kbd&gt; to change ships (you may have to click on the
   map first to get focus). The demo ships are: yellow square (4
   thrusters), green square (like yellow but you can make it
   asymmetric), teal curved, purple curved (like teal but two
   thrusters are broken, so it can't fly properly), blue square (8
   thrusters!), red triangle (goes fast but can't turn well). I
   mostly play with the yellow and blue ships.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Change the ship by dragging the thrusters and adjusting their size
   and orientation. As you do this, watch the graphs.  The bar charts
   show what happens if you press one key at a time.  The polygons
   represent your current flight envelope for two keys at a time. I
   find that I use the &lt;kbd&gt;W&lt;/kbd&gt;+&lt;kbd&gt;A&lt;/kbd&gt; and
   &lt;kbd&gt;W&lt;/kbd&gt;+&lt;kbd&gt;D&lt;/kbd&gt; combinations often, so I watch the chart
   in the lower left. The shaded ovals show the "target" that you
   want to mostly cover if you want a reasonable ship. The yellow and
   blue ships are easy to improve: just increase the power of the
   thrusters and they will fly well. The teal and red ships are
   slightly harder, and the purple ship is near hopeless. In a real
   game the number and power of your thrusters would be limited, and
   fuel efficiency and fuel tank size would be additional factors to consider.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Fly the ship around with &lt;kbd&gt;W&lt;/kbd&gt;=forwards,
      &lt;kbd&gt;S&lt;/kbd&gt;=backwards, &lt;kbd&gt;A&lt;/kbd&gt;=rotate left, &lt;kbd&gt;D&lt;/kbd&gt;=rotate
      right, &lt;kbd&gt;Q&lt;/kbd&gt;=slide left, &lt;kbd&gt;E&lt;/kbd&gt;=slide right,
      &lt;kbd&gt;Z&lt;/kbd&gt;=reset position.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
  &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/spaceship-editor/main.swf"&gt;&lt;img style="width:100%" src="http://lh3.ggpht.com/_kV9ZnGnZL7M/ScXqOqE3qwI/AAAAAAAAAwQ/J5ELoV7c4Lc/s800/Picture%202.png" alt="(screenshot of spaceship editor)"/&gt;&lt;br /&gt;Try the demo.&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;The demo is written with Flash 10 in mind. It should work with Flash 9
   but there may be some visual artifacts (due to bugs in Flash 9 that I
   didn't work around). There are some other minor bugs that I might fix
   someday.
&lt;/p&gt;
&lt;p&gt;I'm finished with the spaceship editor mini-project and haven't
   decided what the next mini-project will be. I really enjoyed working
   on the spaceship physics and editor, but I spent too much time on it,
   and hope to spend less time on the next mini-project.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; [2009-12-05] If you want to try a game that lets you create your own spaceships, check out &lt;a href="http://www.captainforever.com/"&gt;Captain Forever&lt;/a&gt;. It's pretty neat.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-8818639201392620884?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/8818639201392620884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=8818639201392620884' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8818639201392620884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/8818639201392620884'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/03/game-component-spaceship-editor-part-4.html' title='Game Component: Spaceship editor, part 4'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_kV9ZnGnZL7M/ScXONnDA1jI/AAAAAAAAAwA/leck6l_VEfM/s72-c/mouse-drag-state-diagram.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-1496051874242422300</id><published>2009-01-27T22:25:00.001-08:00</published><updated>2009-01-27T22:28:16.721-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Game Component: Spaceship editor, part 3</title><content type='html'>&lt;p&gt;
   I've been trying out a few ideas with quick &amp;amp; dirty demos to see if
   they're at all promising as part of a game. &lt;a href="http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-1.html"&gt;Two posts ago&lt;/a&gt; I talked
   about a spaceship editor, where you could place the thrusters, and the
   “AI” would learn how to pick thrusters that most closely matched your
   desired motion. In the &lt;a href="http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-2.html"&gt;last post&lt;/a&gt; I spent some time describing how I
   spent some time trying to figure out the characteristics of the ship,
   how I learned more about the problem I needed to solve, and some of
   the things I tried to find a “nice” solution to the math. I was really
   happy with the things I had worked on. However…
&lt;/p&gt;
&lt;p&gt;
   The real questions I wanted to answer were:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;
     Is it actually &lt;strong&gt;fun to fly&lt;/strong&gt; a ship with this physics model?
 &lt;/li&gt;

 &lt;li&gt;
     Is it actually &lt;strong&gt;fun to design&lt;/strong&gt; a ship?  In other words, are there interesting designs and tradeoffs?
 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
   Somewhere during the process I realized that getting the “nice”
   solution &lt;a href="http://www.defmacro.org/ramblings/taming-perfectionism.html"&gt;wasn't that important&lt;/a&gt;, and I had probably spent too much time
   on it. (Reading &lt;a href="http://www.gamedev.net/reference/articles/article2259.asp"&gt;this
article&lt;/a&gt;
   reminds me that I get distracted too easily on fun problems and I have
   trouble completing things.) I wasn't getting closer to answering the
   important questions. Instead, I was having fun learning some math that
   I had forgotten 15 years ago. Having fun learning math isn't bad; it's
   just not the main goal.
&lt;/p&gt;
&lt;img align=right style="margin: 1em" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SX6_jm78UnI/AAAAAAAAApw/YqLtPwC5_lc/s800/Picture%204.png" alt="My spaceship flying around"/&gt;
&lt;p&gt;
   To answer the first question, I spent some time in various ships just
   flying around.  My conclusion was &lt;strong&gt;yes&lt;/strong&gt;, it's fun to fly around in a
   world by itself, but &lt;strong&gt;no&lt;/strong&gt;, it doesn't seem like it'd be fun in an
   actual game, where there are other things to do.  And that's when it
   hit me: all that time I spent thinking about the math might have been
   a waste of time (except that it was a lot of fun to learn some math);
   I should first make sure I can make the ships fun to fly.
&lt;/p&gt;
&lt;p&gt;
   I flew around a lot and thought about what bugged me. The main problem
   was that &lt;strong&gt;inertia&lt;/strong&gt; was fun at first but it seemed to get annoying
   after a little while. For example, if I'm moving forwards with
   &lt;kbd&gt;W&lt;/kbd&gt;, and then I rotate left with &lt;kbd&gt;A&lt;/kbd&gt;, I'm still
   moving, but my jets are pointed at an angle. To stop moving you need
   to use a combination of &lt;kbd&gt;S&lt;/kbd&gt; and &lt;kbd&gt;Q&lt;/kbd&gt;. Even worse,
   since it's a keyboard instead of an analog controller, you can't hit
   the right mix of the two to make yourself stop.
&lt;/p&gt;
&lt;p&gt;
   In addition, it wasn't clear to me whether the &lt;strong&gt;controls&lt;/strong&gt; should set
   acceleration, velocity, or target position.  Acceleration was the most
   natural thing, and that's what I started with. But that means when you
   hit any key, you start out slow, then go faster and faster, until it's
   out of control. That might be realistic but it's not much fun.  I
   switched it to setting velocity. But what velocity should I target? I
   arbitrarily chose some multiple K of the acceleration, so that after K
   time you'd reach that velocity.
&lt;/p&gt;
&lt;p&gt;
   I also needed to do more &lt;strong&gt;tuning&lt;/strong&gt;. The mass, moment of inertia,
   friction, and rotation/translation tradeoffs are set arbitrarily. I
   had tried adjusting this but none of the parameters were quite right,
   and every time I changed the physics it got worse, and I had to tune
   to make it better again.
&lt;/p&gt;
&lt;p&gt;
   I tried to answer the second question (whether there are interesting
   ship tradeoffs) by creating several ships. Based on that experience,
   my answer is &lt;em&gt;maybe&lt;/em&gt;.  The ships I made are noticeably different but
   I have a clear favorite.  If there's only one best ship then the ship
   editor's not going to be interesting.  The problem is that the answer
   to the second question depends on what I do with the physics.
&lt;/p&gt;
&lt;p&gt;
   So I decided to work on the physics first.
&lt;/p&gt;
&lt;p&gt;
   I tried tackling inertia directly, with some ideas from a friend:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;Inertia in World Coordinates&lt;/strong&gt; gives me realistic physics for
      flying ships.  This is what I had started with, and this is
      what I was unhappy with. When you're going north, and turn
      left, you keep flying north. The inertia keeps moving you
      &lt;em&gt;north&lt;/em&gt;, even if you face west.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;Inertia in Ship Coordinates&lt;/strong&gt; gives me something that behaves
      more like a vehicle on wheels. When you're going north, and
      turn left, you start going west. The inertia keeps moving you
      &lt;em&gt;forwards&lt;/em&gt;, whatever direction that may be.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;No Inertia&lt;/strong&gt; would mean that you only move when thrusters are
      fired. This is the most extreme change but if inertia is really
      a problem then it's worth a try.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   I also tried treating rotation differently from x and y, because
   rotation seems to lead to some of the situations that make the ship
   less fun to control.
&lt;/p&gt;
&lt;img align=left style="margin: 1em" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SX7AE6aPr-I/AAAAAAAAAp4/_EgUS9izFIA/s800/Picture%203.png" alt="My spaceship flying around"/&gt;
&lt;p&gt;
   It was only after playing with the various options that I learned that
   I do really want inertia in world coordinates.  Sometimes I just have
   to try something to help me learn something (also see &lt;a
href="http://paulbuchheit.blogspot.com/2009/01/communicating-with-code.html"&gt;this
   blog post&lt;/a&gt;).  Having no inertia, or inertia in ship coordinates,
   just didn't feel fun to fly at all, and that's not what I would've
   predicted.  I had the right form of inertia; something else was wrong.
&lt;/p&gt;
&lt;p&gt;
   After all the testing, I realized I wanted inertia but not the full
   effect.  At low speeds, inertia is great, but at high speeds, inertia
   is less fun. With inertia alone it takes as long to speed up as it
   does to slow down again.  It's okay if it takes a second or two to
   reach a high speed.  But when I let go of the keys I want the ship to
   come to a stop pretty quickly.  I added a force to slow the ship down.
   I tried three approaches:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;Constant&lt;/strong&gt; force decreases velocity V by up to K. This can be
      interpreted as surface friction.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;Linear&lt;/strong&gt; force decreases velocity V by K*V. I don't know what
      this might correspond to in physics, but in the calculations it
      corresponds to “reducing” inertia.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;
   &lt;strong&gt;Quadratic&lt;/strong&gt; force decreases velocity V by K&lt;em&gt;V&lt;/em&gt;V. This can be
      interpreted as air resistance.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   All three of them helped. After trying and tuning the three I decided
   that the linear force reduction was the most pleasant, but still not
   ideal.  With quadratic, the problem I ran into (which I might have
   predicted if I were smarter) was that you can't increase your maximum
   velocity much if you add thrusters. Instead, it was largely determined
   by the air resistance. That would be fine if I were creating just one
   ship, but for the ship editor to be interesting, I need the number and
   power of the thrusters to actually matter!  Constant friction left too
   much of your motion determined by inertia at higher speeds.  The
   linear slowdown felt the best. I can't justify it if I were going for
   realism, but I'm going for fun, not realism.
&lt;/p&gt;
&lt;p&gt;
   I think flying the ship can be made fun.  The next question to tackle
   is whether there are interesting tradeoffs in ship design.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-1496051874242422300?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/1496051874242422300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=1496051874242422300' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1496051874242422300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1496051874242422300'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-3.html' title='Game Component: Spaceship editor, part 3'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_kV9ZnGnZL7M/SX6_jm78UnI/AAAAAAAAApw/YqLtPwC5_lc/s72-c/Picture%204.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5502058233813958214</id><published>2009-01-11T13:10:00.000-08:00</published><updated>2009-01-11T16:14:01.490-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Game Component: Spaceship editor, part 2</title><content type='html'>&lt;p&gt;
   In the &lt;a href="http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-1.html"&gt;last post&lt;/a&gt;, I described a fun problem I wanted to play with, and
   my initial attempt to solve it.  I made several ships, figured out how
   their thrusters worked, and built a simple system for flying.  The
   keys were &lt;kbd&gt;W&lt;/kbd&gt; for forwards, &lt;kbd&gt;S&lt;/kbd&gt; for backwards,
   &lt;kbd&gt;Q&lt;/kbd&gt; for slide left, &lt;kbd&gt;E&lt;/kbd&gt; for slide right,
   &lt;kbd&gt;A&lt;/kbd&gt; for rotate left, and &lt;kbd&gt;D&lt;/kbd&gt; for rotate right. Once
   I flew them around and saw that it was fun, and ship design might be
   interesting for the player, I wanted to understand better the
   characteristics of the ships. So I did something that often helps me:
   visualize the data.
&lt;/p&gt;
&lt;p&gt;
   In this diagram you can see the black dots are the possible outputs
   for the first test ship, viewed from three different perspectives.
   You can see that it's not completely random.  There's a definite shape
   there.  The variety of shapes is what makes this problem
   interesting. I plotted these for all of my test ships, and learned a
   lot. For example, look at the lower left plot (with the &lt;kbd&gt;A&lt;/kbd&gt;–&lt;kbd&gt;D&lt;/kbd&gt; + &lt;kbd&gt;W&lt;/kbd&gt;–&lt;kbd&gt;S&lt;/kbd&gt; axes). From it we can learn that the ship flies forwards quickly (&lt;kbd&gt;W&lt;/kbd&gt;) but backwards slowly (&lt;kbd&gt;S&lt;/kbd&gt;). It can rotate left (&lt;kbd&gt;A&lt;/kbd&gt;) and right (&lt;kbd&gt;D&lt;/kbd&gt;) slowly. Going forwards makes it easier to rotate quickly; going backwards makes it harder. 
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="http://lh4.ggpht.com/_kV9ZnGnZL7M/SWpQ109q11I/AAAAAAAAAmU/VRTLFj6twak/s800/Picture1.png"&gt;&lt;img src="http://lh4.ggpht.com/_kV9ZnGnZL7M/SWpQ109q11I/AAAAAAAAAmU/VRTLFj6twak/s400/Picture1.png" alt="Diagram of random output configurations"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
   While flying the ship I noticed however that there was a second
   problem I hadn't appreciated at first.  When choosing outputs that are
   “close” to the desired output, a difference of +3 to +4 is nowhere
   near as significant as a difference of 0 to +0.1.  When the player
   wants zero movement, it's very important to keep it zero.  If one key
   is pressed down, then there should be one non-zero in the output; if
   two keys are pressed then there should be two non-zeros.  The most
   common case for the random input/output pairs is to have no zeros, but
   the most common case for the player is to be pressing just one key,
   and thus needing two zeros!
&lt;/p&gt;
&lt;img align="right" src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SWk7v_WlhRI/AAAAAAAAAlw/3A6sigBNplk/s288/IMG_0039.JPG" alt="I often work best when alternating between theory and practice."/&gt;
&lt;p&gt;
   Because my random input/output approach was fun but didn't handle the
   one and two-keystroke cases well, I also looked a few different
   analytical approaches to compute the reverse mapping directly. I
   looked at the &lt;a href="http://en.wikipedia.org/wiki/Pseudoinverse"&gt;pseudo-inverse operation&lt;/a&gt;, which is like matrix
   inverse but works with non-square matrices. However, it didn't look
   like it would help me. I also looked at it as a &lt;a href="http://en.wikipedia.org/wiki/Linear_programming"&gt;linear programming
optimization problem&lt;/a&gt;. That approach looked promising but the
   &lt;a href="http://en.wikipedia.org/wiki/Simplex_algorithm"&gt;Simplex algorithm&lt;/a&gt; was more than I wanted to implement.
&lt;/p&gt;
&lt;p&gt;
   None of the mathematical approaches I saw directly matched the problem
   I was trying to solve.  It's easy to add the constraint about zeros to
   a linear programming problem but not to the matrix pseudo-inverse.  It
   might be made to work with the random input/output pairs, by adding
   some weights to the output components, but the outputs generated from
   random inputs almost never contained zeros, so I'm never going to get
   exactly what I want.
&lt;/p&gt;
&lt;p&gt;
   One of my habits that seems to work well for me is to alternate
   between working things out on paper and writing code.  The ship
   thruster physics, the input/output pairs, and the matrix math I first
   worked on paper, then implemented it.  So I went back to paper and pen
   for this problem.  Can I increase the number of outputs that contain
   some zeros?
&lt;/p&gt;
&lt;p&gt;
   First I tried changing the way I picked random inputs, and favored 0
   and 1 instead of evenly uniformly choosing any number between 0 and 1.
   That didn't help much (but I later had an insight related to this
   change, so maybe it was useful after all).  I decided I needed to
   attack the problem directly.  The idea of interpolating between output
   points was still in my head, and I used that here.  If I picked two
   points on opposite sides of a zero plane, I could find some
   interpolation that was on the plane.  I took pairs of the random
   input/output pairs and solved for any zeros on the line
   between them.  This worked well!  I now had a new set of points that
   had one zero in the output.  By applying the algorithm again, I could
   find a set of outputs that had two zeros.
&lt;/p&gt;
&lt;p&gt;
   In this diagram you can see the black dots are the random outputs
   projected down to the three planes, and also the white dots, which are
   formed from finding the point in between two black dots that
   intersects the plane.  The space covered by white dots is more limited
   than that for black dots.  That's because there are some wild
   movements that can't be controlled if you try to restrict one of the
   outputs to zero.
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="http://lh4.ggpht.com/_kV9ZnGnZL7M/SWpQ13UissI/AAAAAAAAAmc/hO5Ft8dIRxo/s800/Picture2.png"&gt;&lt;img src="http://lh4.ggpht.com/_kV9ZnGnZL7M/SWpQ13UissI/AAAAAAAAAmc/hO5Ft8dIRxo/s400/Picture2.png" alt="Diagram of restricted output configurations"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
   I had up to 1000 random input/output pairs.  Solving the equations for
   every zero plane and every pair that was on opposite sides of the
   plane meant I needed to solve a matrix equation around 750,000 times.
   It took a while but it was reasonable. Applying this again to get the
   outputs with two zeros would've been too slow.  And I wanted this to
   be fast enough so that you could see the flight characteristics as you
   were editing the spaceship.
&lt;/p&gt;
&lt;p&gt;
   Have you ever noticed that you often find something or think of
   something only after you stop looking for it?  I've noticed that this
   happens for me when solving problems.  I had gotten stuck with the
   brute force technique and I needed something smarter, but I was
   getting nowhere.  So I stopped working on the problem.  A few days
   later, while playing a game, I had an insight that should have been
   obvious from the start.
&lt;/p&gt;
&lt;p&gt;
   All the random inputs are thruster settings from 0.0 to 1.0.  We're
   taking matrix M and multiplying it by a vector T, which must be in a
   fairly small space.  If there are N dimensions, T is an N-dimensional
   vector, and all its components are between 0.0 and 1.0.  That means …
   the space of all valid thruster configurations is a unit N-dimensional
   hypercube.
&lt;/p&gt;
&lt;p&gt;
   A wise man once told me that it's sometimes easier to solve the
   general case than the specific case.  I had been trying to solve the
   specific case, of a single input mapped to a single output.  And then
   I'm using computational power to handle lots of them.  The general
   case is to take the &lt;em&gt;entire hypercube&lt;/em&gt; and transform it to the output,
   and see what comes out.
&lt;/p&gt;
&lt;p&gt;
   What comes out is a polyhedron in 3 dimensions.
&lt;/p&gt;
&lt;p&gt;
   This insight seemed like it came out of nowhere, while I was playing a
   game, killing orcs.  But when I thought about it more, I think it
   wasn't out of nowhere. If I were smarter I would've figured it out
   from the very beginning, but some things I had thought touched on the
   hypercube approach. One clue was that when I picked random numbers for
   inputs, I found that it useful to bias towards 0.0 and 1.0.  My
   experiments were guiding me towards choosing the vertices of the
   hypercube.  Another clue was that in linear programming, you can think
   of the valid space as a convex polyhedron in some higher dimensional space.
   I had spent some time thinking about what the polyhedron represented
   in my problem but I wasn't able to make the connection.  A third clue
   was that plotting the black and white dots made it look like there
   were simple polygons involved.
&lt;/p&gt;
&lt;p&gt;
   For N thrusters the hypercube has 2&lt;sup&gt;N&lt;/sup&gt; vertices.  In this
   diagram you can see the hypercube vertices, multiplied by the matrix,
   do cover the space that the random points covered.  As before, the
   black dots are the random sample.  The colored dots are the vertices
   of the hypercube.
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="http://lh5.ggpht.com/_kV9ZnGnZL7M/SWpQ2-6Dd7I/AAAAAAAAAmk/YEkUYZHr4wA/s800/Picture4.png"&gt;&lt;img src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SWpQ2-6Dd7I/AAAAAAAAAmk/YEkUYZHr4wA/s400/Picture4.png" alt="Diagram of hypercube vertices"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
   Instead of picking lots of random points, I should pick these points.
   And then I can take every pair of these and find the interpolation
   that has a zero output.  And then I can take every pair of those and
   find the outputs with two zeros.
&lt;/p&gt;
&lt;img align="right" src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SWlJMW5eJxI/AAAAAAAAAl8/uDlZPrMP638/s288/IMG_0018.JPG" alt="Sometimes I work things out on paper"/&gt;
&lt;p&gt;
   I worked this out on paper. Page after page of solving equations for
   test ship 1, following by plotting things out on graph paper,
   convinced me that this was quite promising.
&lt;/p&gt;
&lt;p&gt;
   I was really happy with myself.  I had figured out a much more elegant
   solution that didn't involve random numbers.&lt;br /&gt;

&lt;/p&gt;
&lt;p&gt;
   I took the equations I solved on paper and wrote some code to solve
   them.  I tried it out on several different ships.  And then I ran into
   a problem.  For one of my ships, with 8 thrusters, the algorithm still
   ran rather slowly.  Why?  Well, 2&lt;sup&gt;8&lt;/sup&gt; is 256.  Finding the
   one-zero outputs involved examining 2&lt;sup&gt;15&lt;/sup&gt; pairs in 3
   dimensions, or around 100,000 systems of equations to solve.  It took
   a few seconds, but I hadn't gotten to the one-zero case yet, which is
   the really expensive one.  For this ship I was almost as slow as the
   random point approach. The random points were slow but equally slow
   for all ships, whereas the hypercube vertices got worse every thruster
   you added. Ick. While starting a cube lamp on my desk, I realized that
   all the useful zeros should occur along edges, not as interpolations
   between two arbitrary points.  I could reduce 2&lt;sup&gt;8&lt;/sup&gt; pairs X
   2&lt;sup&gt;7&lt;/sup&gt; pairs to just 2&lt;sup&gt;8&lt;/sup&gt; pairs X 8.  Much faster!
   However, that was only the one-zero outputs. I still had to run the
   interpolations again, to find the two-zero outputs. And even with the
   optimization that was around 1,000,000 systems of equations.  I was
   sure there was another optimization involving surfaces instead of
   edges but I just couldn't figure out what it was.
&lt;/p&gt;
&lt;p&gt;
   So I took another break.  I spent some time plotting what I had, to
   see if there were insights I could draw from the visualization.  I
   plotted sets of points and found that many of them just aren't
   relevant because they're in the “interior” of the areas.  All I care
   about is the perimeter.  To compute the perimeter in two dimensions is
   a well-known problem: &lt;a href="http://en.wikipedia.org/wiki/Convex_hull"&gt;convex hull&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
   I thought about how to compute a convex hull, and it seemed rather
   simple. I wrote down my notes, then proceeded to see what the
   &lt;a href="http://en.wikipedia.org/wiki/Convex_hull_algorithms"&gt;standard algorithms&lt;/a&gt; were. None of them seemed as simple as my
   algorithm, which meant my algorithm probably has a bug. But I couldn't
   see what it was, so I decided to let it wait a bit.  A few days later,
   still unable to think of a flaw, I sketched out the math on paper,
   then implemented it. Although I had a few bugs in the code, the
   algorithm itself worked.
&lt;/p&gt;
&lt;p&gt;
   Once I had the convex hull algorithm available, my next step was to
   use it to simplify the one-zero outputs into a convex hull before
   finding the two-zero points. 
&lt;/p&gt;
&lt;p&gt;
   In this diagram you can see the points that make up the convex
   hull. As before, the white dots are the interpolations between random
   points, to find positions on the zero plane. The colored points with
   black borders around them are the interpolations between hypercube
   vertices, fed into the convex hull algorithm.  You can see that all
   the points I computed from the random set lie within the convex hull
   computed from the hypercube vertices.
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="http://lh6.ggpht.com/_kV9ZnGnZL7M/SWpQ3RSKCZI/AAAAAAAAAms/sVB-l7MNSuQ/s800/Picture5.png"&gt;&lt;img src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SWpQ3RSKCZI/AAAAAAAAAms/sVB-l7MNSuQ/s400/Picture5.png" alt="Diagram of convex hulls"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
   In fact the two-zero points always occur between adjacent points in
   the convex hull, so I had gotten yet another optimization out of this
   change.  However, I discovered that my convex hull algorithm does have
   a flaw. When there are collinear points it doesn't always remove all of
   them. The flaw remains in my code; it doesn't seem to be a big deal in
   practice, because my code is now “fast enough”. For each of the five
   test ships, generating the flight parameters takes less than a second.
&lt;/p&gt;
&lt;p&gt;
   Another thing that wasn't clear to me when I started was that when you
   press both &lt;kbd&gt;W&lt;/kbd&gt; and &lt;kbd&gt;Q&lt;/kbd&gt;, you want to go both left and
   forwards, but there's not a fixed ratio between the two. Sometimes you
   can get both and sometimes you have to make a tradeoff, and none of
   the techniques worked out of the box for that. I think this might be
   something to leave to the ship designer, once the flight
   characteristics are known. For example, in the above diagrams you
   could have a way to mark what you want a combination of keys to do.
&lt;/p&gt;
&lt;p&gt;
   It's been a fun journey.  I've taken off some rust from my skills.
   And I learned a bit more about linear programming, the simplex
   algorithm, physics, and convex hulls.
&lt;/p&gt;
&lt;p&gt;
   However, I haven't yet written an editor. But I now have the physics and math
   worked out, so once I have an editor, you'll be able to see the flight
   characteristics of the ship you're editing.  I'll post the demo and source here.  It will be nice if there
   are interesting tradeoffs for the player.  For example, if you put
   jets on the wingtips, you can rotate very quickly, but perhaps it adds
   a lot of mass to make the wings sturdy enough to take jets, and that
   extra mass slows you down in terms of forward acceleration. Once I
   have the editor I'll get a better feel for whether there are
   interesting tradeoffs to be made, and whether this would be useful to have in a game.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5502058233813958214?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5502058233813958214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5502058233813958214' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5502058233813958214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5502058233813958214'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-2.html' title='Game Component: Spaceship editor, part 2'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_kV9ZnGnZL7M/SWpQ109q11I/AAAAAAAAAmU/VRTLFj6twak/s72-c/Picture1.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6418058712075030925</id><published>2009-01-10T14:59:00.000-08:00</published><updated>2009-01-12T11:53:51.377-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Game Component: Spaceship editor, part 1</title><content type='html'>&lt;p&gt;
   I've been playing Spore recently. It's an interesting game. One of the
   criticisms is that the physical characteristics of the things you do
   in the editor don't make a difference to gameplay. For example, having
   wide legs or narrow legs or four legs or six legs doesn't affect your
   speed. Only the +Speed items affect speed. Only in the Cell stage does
   placement matter.  I read some of their reasoning behind this design
   and I agree with it. In a game where creativity is more important than
   realism, simplifying that aspect of the game will encourage people to
   be more creative in their designs.  I know that if the number of legs
   actually mattered for gameplay, I wouldn't have made my creature hop
   around on one leg.
&lt;/p&gt;
&lt;p&gt;
   Although I think they made the right decision for Spore, I was
   inspired to explore the alternative: something where the way you
   design your creature matters a great deal. To fit in with the
   2d top-down theme I've been using (see the &lt;a href="http://simblob.blogspot.com/2008/12/game-component-radial-base-layout.html"&gt;space station
   miniproject&lt;/a&gt;), I'm using spaceships instead of creatures.
&lt;/p&gt;
&lt;p&gt;
   The main idea for this miniproject is that you'd design the ship, and
   then the “AI” would learn how to fly the ship you designed.  For
   example, let's consider the following ship with four thrusters:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://lh5.ggpht.com/_kV9ZnGnZL7M/SWkquuT5p_I/AAAAAAAAAks/6b-991_att8/s800/Picture6c.png" alt="Diagram of Test Ship 1 and its thrusters"/&gt;
&lt;/p&gt;
&lt;p&gt;
   If you fire either thruster A or B, you'd end up rotating. But if you
   fire both at once, you would go forwards.  Given a set of thrusters
   (location on the ship, direction they fire, and their maximum power),
   I can calculate the effect on the ship (acceleration and rotational
   acceleration).  Initially I was calculating the force to be only what
   was transmitted along the A→O vector, but later I realized that
   because the ship is rigid, the entire force gets transmitted to the
   entire ship, and is independent of the location of the thruster.
   Since thruster A fires in direction (0, +2), the force on the ship is
   (0, -2). Rotation is slightly trickier, as we need to calculate
   torque, and take into account the rotational moment of inertia.  For
   now I'm assuming the mass and moment of inertia are constants, but
   later I'll compute these based on the characteristics of the ship. The
   torque does take into account the position of the thruster, and we
   have to compute the cross product of the A→O vector (-2, 4) and the
   force vector (0, -2).&lt;br /&gt;

&lt;/p&gt;
&lt;p&gt;
   The forward mapping from thrusters to forces turns out to be a matrix
   multiplication.  Each thruster is a column and each effect on the ship
   is a row.  Doing this for each of the thrusters, we get the thruster
   matrix M mapping thrusters to force and torque:
&lt;/p&gt;
&lt;table class=standard style="margin-left:2em;padding:3pt;text-align:right"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;M:&lt;/th&gt;&lt;th&gt;A&lt;/th&gt;&lt;th&gt;B&lt;/th&gt;&lt;th&gt;C&lt;/th&gt;&lt;th&gt;D&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Fx &lt;/th&gt;&lt;td&gt;    0&lt;/td&gt;&lt;td&gt;   0&lt;/td&gt;&lt;td&gt; -0.5&lt;/td&gt;&lt;td&gt;  0.5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Fy&lt;/th&gt;&lt;td&gt;-2 &lt;/td&gt;&lt;td&gt; -2&lt;/td&gt;&lt;td&gt;  0.5 &lt;/td&gt;&lt;td&gt; 0.5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Tq &lt;/th&gt;&lt;td&gt;   10 &lt;/td&gt;&lt;td&gt;-10 &lt;/td&gt;&lt;td&gt;1.25&lt;/td&gt;&lt;td&gt;-1.25&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
   Given a thruster configuration vector T, M∙T gives us the forces
   acting on the ship.
&lt;/p&gt;
&lt;p&gt;
   The real problem though is reversing that mapping.  The player presses
   a key to move forwards, and I need to figure out which combination of
   thrusters best accelerates the ship forwards.  What value of T leads
   to M*T being close to [ 0 1 0 ]?
&lt;/p&gt;
&lt;p&gt;
   The simplest approach is brute force. So I started with that first. I
   generated lots of random inputs and calculated their outputs. Then
   when I needed some particular output, I scanned them all and picked
   the input that most closely generated that output.  Over multiple
   simulation cycles, any errors would be corrected by picking different
   input/output pairs.  I could make this even more stable by iterating
   within a single simulation cycle, and interpolating among the results.
&lt;/p&gt;
&lt;p&gt;
   This approach worked reasonably well!
&lt;/p&gt;
&lt;p&gt;
   The ship behavior was interesting. My first test ship (the one I'm
   using for these examples) moved reasonably well forwards and
   backwards, and could rotate well, but it couldn't slide left and right
   quickly. 
&lt;/p&gt;
&lt;p&gt;
   My second ship is a variant of the first. When moving forwards it can
   rotate well, but if you're stationary or going backwards the rotation
   is limited. When you fly it you'll see that if you want to rotate, you
   need to move forwards at the same time. Here's what it looks like:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SWkqurmCCDI/AAAAAAAAAk0/Z3wQOfxofwQ/s800/Picture10.jpg" alt="Closeup of Test Ship 2"/&gt;
&lt;/p&gt;
&lt;p&gt;
   My third ship had reasonable movement, and rather asymmetric: it could
   rotate and slide left at the same time, or rotate and slide right at
   the same time, but it was much slower if you rotated left while
   sliding right or vice versa. It looks a little different from the
   first two, but right now that makes no difference in the physics:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://lh3.ggpht.com/_kV9ZnGnZL7M/SWkqujkjNfI/AAAAAAAAAk8/IZUkDpbaCfs/s800/Picture7.jpg" alt="Closeup of Test Ship 3"/&gt;
&lt;/p&gt;
&lt;p&gt;
   My fourth ship is a damaged version of the third ship, to see if
   having inoperable thrusters would make for interesting gameplay. Going
   forwards would also make you spin around in circles. It was fun to
   play with in the prototype but I'm not convinced it'd be fun in a game. You
   can see why it's unstable:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://lh3.ggpht.com/_kV9ZnGnZL7M/SWkqu-ombfI/AAAAAAAAAlE/f8sFyX01yLA/s800/Picture8.jpg" alt="Closeup of Test Ship 4"/&gt;
&lt;/p&gt;
&lt;p&gt;
   My fifth test ship could rotate very quickly but couldn't go backwards
   at all (at least until I fixed a bug in the physics calculations), so
   you'd turn around and go forwards in order to stop moving. This might
   be a ship you can't build until later stages of the game, when you've
   gained building points or parts or money.  Just look at how much power
   it has:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://lh6.ggpht.com/_kV9ZnGnZL7M/SWkq0BGQ0_I/AAAAAAAAAlM/9mvtc4FF9P8/s800/Picture9.jpg" alt="Closeup of Test Ship 5"/&gt;
&lt;/p&gt;
&lt;p&gt;
   At this point the prototype made me think there was something potentially
   fun for a game.  You could design your own ship and make
   tradeoffs. The game “AI” would learn how to map your keys to thruster
   movements, and the player would then have to learn best to use the
   controls for navigation and combat. For example, having to turn a ship
   around to stop is unusual but you might design a ship that way if you
   could get lightning-quick rotation in return.  You might design
   different ships for different levels.  Or you might learn how to play
   a ship so well that you don't want to switch to something else with
   different characteristics. 
&lt;/p&gt;
&lt;p&gt;
   I knew the ships were all different in their behaviors but I didn't
   understand what their limits were.  So my next step was to try to
   understand the flight characteristics of the ships.  That's for the next post.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6418058712075030925?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6418058712075030925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6418058712075030925' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6418058712075030925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6418058712075030925'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2009/01/game-component-spaceship-editor-part-1.html' title='Game Component: Spaceship editor, part 1'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_kV9ZnGnZL7M/SWkquuT5p_I/AAAAAAAAAks/6b-991_att8/s72-c/Picture6c.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4624748988856676189</id><published>2008-12-01T10:34:00.000-08:00</published><updated>2009-01-10T16:09:10.433-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Game Component: Radial Base Layout</title><content type='html'>&lt;p&gt;
I haven't had the time and energy to work on a full game (the &lt;a href="http://simblob.blogspot.com/2007/01/transportation-mini-game-rough-design.html"&gt;transportation game&lt;/a&gt; is on hold) but instead I'm playing with lots of little ideas, some of which turn into &lt;a href="http://simblob.blogspot.com/2008/06/game-idea-shifting-game-maps.html"&gt;demos&lt;/a&gt;. This week's idea is to algorithmically generate layouts for space stations or space bases, so that they all look different. Originally I had a lot more variety in mind, but for the demo, I only implemented simple radial layouts:
&lt;/p&gt;
    &lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="650" height="415" id=""&gt;&lt;param name="movie" value="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/radial-base/spacestationdemo.swf"&gt;&lt;object type="application/x-shockwave-flash" data="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/radial-base/spacestationdemo.swf" width="650" height="415"&gt;
      &lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/radial-base/example.png" alt="(example radial space base layout)"&gt;
      &lt;br&gt;
      (This is an example layout produced by the Flash demo)
    &lt;/object&gt;&lt;/object&gt;
&lt;p&gt;
  I wrote &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/radial-base/"&gt;some notes about the algorithm, the source code, and how to use this in a game&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Update:&lt;/strong&gt; [2008-12-02] I forgot to mention my motivation: I was looking for something very simple that would compile to a small size and generate “programmer art”. The layout and rendering for this compiles to under 5k, and I'd guess that it could be under 3k for something more specialized. The small size and large variety makes this a reasonable thing to include in a browser-based game.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4624748988856676189?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4624748988856676189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4624748988856676189' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4624748988856676189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4624748988856676189'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/12/game-component-radial-base-layout.html' title='Game Component: Radial Base Layout'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4015705959136868163</id><published>2008-11-09T08:03:00.000-08:00</published><updated>2008-11-09T08:42:52.692-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Reflexes and Brains</title><content type='html'>&lt;p&gt;
The brain is a complex organ with complex processing. But it's slow. Early AIs were written to explore the highest level of brain functions — things like planning, logic, natural language, creativity, problem solving, mathematics. Like the higher levels of the brain, solving these problems is slow. In game AI, planning and pathfinding are examples of the higher level processing, and these are often slow. 
&lt;/p&gt;
&lt;p&gt;
In the body, when fast reactions are needed, we have &lt;strong&gt;reflexes&lt;/strong&gt;: a fast but dumb reaction that occurs before the brain can fully process and respond to a signal. The classic example is putting a hand on a hot potato – you will pull your hand away before the brain even receives the pain signal. Many reflexes are handled by the spinal cord, before the signals reach the brain.
&lt;/p&gt;
&lt;p&gt;
The body has both:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A global &lt;strong&gt;slow, smart&lt;/strong&gt; system: processing in the brain&lt;/li&gt;
&lt;li&gt;A local &lt;strong&gt;fast, dumb&lt;/strong&gt; system: reflexes closer to where the input occurred&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In game AI we can often do the same. An example is in games where pathfinding is slow, and has to be split up among several frames. We need to give instant feedback to the player when the unit is clicked. If pathfinding is slow, then we need something else in its place. In some games, you'll see animation and sound for the unit getting ready to move. But the reflex-inspired approach would be to have a secondary pathfinding system that's fast and dumb, and have the unit start following that path right away. The most straightforward approach would be to start moving in a straight line; another approach would be to see if any nearby units are moving to the same general area, and start following them. The slow, smart system can fix the path later. In some cases you don't need the smart system at all because the dumb path is fine. That way, you can get &lt;em&gt;both&lt;/em&gt; instantaneous action &lt;em&gt;and&lt;/em&gt; good paths.
&lt;/p&gt;
&lt;p&gt;
In planning tasks we also have places where reflexes can be useful. For example, suppose three different squads are attacked simultaneously. Their reflex action should be to fight back. In the background a slower processing task can analyze these three positions, the size of the attacking forces, and the information gathered from scouting. It can guess what the enemy is going to do next, and order all three squads to fall back to a safer position.  Fire first, then fall back, instead of waiting for the analysis before performing any action.
&lt;/p&gt;
&lt;p&gt;
Lots of games already use these techniques. They're part of a general pattern: use both slow/smart and fast/dumb event handlers, so that you can react quickly and then go back and react smartly in cases where you need it.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4015705959136868163?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4015705959136868163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4015705959136868163' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4015705959136868163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4015705959136868163'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/11/reflexes-and-brains.html' title='Reflexes and Brains'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4008513023231412502</id><published>2008-11-03T08:56:00.001-08:00</published><updated>2009-01-10T19:16:02.811-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Multiple clients for the same game</title><content type='html'>&lt;p&gt;
When I'm interacting with my computer, there's a range of interfaces I
use. On the “high” end, there are full screen specialized UIs
sometimes with specialized controllers.  I have a highly customized
World of Warcraft interface that's tuned for the &lt;a
href="http://www.amazon.com/dp/B000GP844S"&gt;special keyboard I got for
playing games&lt;/a&gt;. These UIs typically use your full attention, and
you don't do anything else on the computer at the same time. On the
“low” end, there are simple interfaces that are usually text-based and
line-at-a-time. Twitter and instant messaging let me send and receive
short lines of text. These UIs typically use very little attention,
and sit unobtrusively on the side while you do something else.
&lt;/p&gt;

&lt;p&gt;
Most games I see are on the “high” end. They have specialized
interfaces that you have to learn, and you're not often
multitasking. Browser based games are somewhere in the middle. They're
not using up the full screen, they have simpler UIs that fit with the
browser's UI, and you can have other things going on at the same time,
although you'll probably ignore them if the game requires your full
attention.
&lt;/p&gt;

&lt;p&gt; For some kinds of games I think it would make sense to have multiple
interfaces to the same game. Outside of games, you see examples
like EBay, which has a main interface (through a web browser), some
“rich client” applications that you can download, and mobile phone
alerts. They all access the same database. You can get more out of the
rich client, but it's not something you run all the time. You do have
the mobile alerts on all the time, but you can't do very much with
that interface. Also look at television shows like Lost or Heroes,
which have a main “rich” interface through the TV show, but also
expose other aspects of the show through their web site, novels, discussion
forums, comic books, and games. The Matrix series of movies had other
aspects of the storyline revealed in comics, anime, and video games. &lt;/p&gt;

&lt;p&gt; What kinds of games would benefit from multiple clients? I think
it's most useful in games that have interactions with other people. In
these games, things can be going on when you're not playing. A
lightweight client would be useful for finding out what's going on,
and perhaps inducing you to play with the full interface. You already
see notification of this sort in a very simple setting: play-by-email
Chess or Go. There's the game itself, and there's a lightweight
communication mechanism (email) that lets you find out what's going
on. But I'd like to see this in a lot more games.  For example, in
Halo 3, it would be nice to see if my buddies are playing
online. Imagine an IM bot that showed in its status message how many
buddies were online. Even better, what if you could talk to that bot
to chat with your buddies in the game, and see their replies in the IM
window. That way you could see what was going on, even if you're not
able to play right away. And if you saw that your buddies have been
playing quite a bit, you might go into the living room and boot up the
XBox. Second Life, World of Warcraft, and any other game with a chat
interface might benefit from having chat interoperate with an IM
client.&lt;/p&gt;

&lt;p&gt; Another kind of game I'd like to see with multiple clients is
persistent world games. There are things going on in the world when
you're not playing, and it'd be nice to keep track of these. For
example, in my brother's game, &lt;a
href="http://en.wikipedia.org/wiki/Barren_Realms_Elite"&gt;Barren Realms
Elite&lt;/a&gt;, you'd send attack forces out to distant worlds, and the
attack would happen at some time, usually when you weren't
playing. It'd be nice to have a web page or RSS feed or gadget (Mac
Dashboard, Vista sidebar, etc.) that showed me the status of my attack
force and the outcome of the battle. These days, MMOs are the most
obvious sort of game where this would be useful. In World of Warcraft,
I'd like to know that Stormwind City is under attack by 60 Horde, or
that my guild just defeated the bosses of Karazhan. The state of the
world could be displayed in a web page, and major attacks could be
sent as IM or email or RSS alerts. &lt;/p&gt;

&lt;p&gt; Another sort of interaction I'd like with a game is for part of
the game – not just status or chat – to be accessible in a lightweight
client. In EVE Online, I'd like to track the economic game – my buy and sell orders, as well as production – even when I'm not in the full game client. EBay
mobile alerts likely increase people's usage of EBay; my guess is that
having that lightweight client that lets you track your EVE Online
business dealings would make you play EVE Online more. &lt;/p&gt;

&lt;p&gt; Even in single player games, there are some interactions with
other people. For example, suppose a new high score in Scrabulous was
sent to all your Facebook pals. That'd both remind people to play
Scrabulous, and it would also encourage everyone to try to beat that
high score.  Scrabulous is a Facebook game, but you could imagine
doing the same with other games. If XBox achievements were sent to my
Facebook account, it'd be more fun to get those achievements than
if people saw them only when they turned on their XBox. &lt;/p&gt;

&lt;p&gt; To summarize, I'd like to see a lot more games with multiple interfaces. Some ideas are: &lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Status&lt;/strong&gt; (web, IM status) to passively see what's going on in the game, even when I'm not there.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alerts&lt;/strong&gt; (RSS, email, IM, SMS texting) to actively be notified of major events in the game.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chat&lt;/strong&gt; (IM, email) to allow communication between people playing right now and people who might not play until later.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Play&lt;/strong&gt; (web) to allow playing some subset of the game through an interface that I can use when I'm doing other things.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; For some, the lightweight game will augment the full game. Many
will end up participating in only the lightweight part of the
game. For others, the lightweight game will be a gateway that leads
them to try and enjoy the full game. I think that's a good thing. Not
everyone uses all the EBay clients; not everyone who watches Heroes
reads the comic books and plays the online games; not everyone who
watched The Matrix also played the game. Different people will
participate in different ways. Use an interface that's simple and widely accessible to complement the interface that's rich but not there all the time. We'll have much more interesting
games when lots more people participate in them. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4008513023231412502?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4008513023231412502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4008513023231412502' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4008513023231412502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4008513023231412502'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/11/multiple-clients-for-same-game.html' title='Multiple clients for the same game'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6162123123634861403</id><published>2008-08-19T22:21:00.000-07:00</published><updated>2008-08-19T22:34:14.163-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Social structures in MMOs</title><content type='html'>&lt;p&gt;
One of the things I’ve been wondering about in WoW is that real relationships tend to have multiple social circles, but in WoW I’m forced to have just one guild. That leads to barriers between groups, and competition between groups for members.
&lt;/p&gt;
&lt;p&gt;
I‘d like to see multiple orthogonal social groups in games. Second Life for example has groups that you can join, but you can be in multiple groups at a time. Each group has its own chat channel. In addition you’re in an informal family group. You can choose your first name but there are a small number of last names available for each batch of new players. When you see a stranger with the same last name, you have a connection with them, without having joined any of the same groups. The explicit links (groups) are augmented with implicit links (last names). In games, classes and races and professions could serve a similar purpose. In practice though I rarely see people make connections based on last names or classes or professions or race. Perhaps it’s because there are too many people in each group, so you don’t feel kinship. 
&lt;/p&gt;
&lt;p&gt;
In an epic MMO, there are events in a shared history that could form implicit social links. For example, if a game has large, difficult battles, all the participants in a battle form an implicit social group. If a game has a way to build things, the people who built in the same town have a connection with each other. If a game has an economy, the people in the same business or frequent trading partners have a connection. When I’m in a town and pass by someone who has a shared history with me, I‘d like to see an icon or color so that I know I have a connection with this person. I might wave or give them a beneficial spell or interact in some other way. A shared chat channel or mailing list might be nice too. Instead, in WoW, I walk by strangers and don‘t care about them.
&lt;/p&gt;
&lt;p&gt;
If we had many different ways for people to build social connections, and reinforce them with game features, we’d end up with a much richer social structure in games.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6162123123634861403?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6162123123634861403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6162123123634861403' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6162123123634861403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6162123123634861403'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/08/social-structures-in-mmos.html' title='Social structures in MMOs'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3392978520097554979</id><published>2008-06-16T11:10:00.000-07:00</published><updated>2008-07-31T09:08:25.153-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Titan Quest</title><content type='html'>&lt;p&gt;
I've been playing an old RPG&lt;sup&gt;*&lt;/sup&gt; called Titan Quest. Two word summary: Diablo Clone. Diablo 2 was lots of fun, and so is Titan Quest.
&lt;/p&gt;
&lt;p&gt;
One thing that struck me about the game design is that it keeps the game simple at the very beginning.  You start out as a generic character, wearing generic clothing.  The only thing you have to decide at the beginning is your name and gender.  Very simple.  So simple in fact I thought I was missing something when I created my character. World of Warcraft, which also delays a lot of complexity (talents, spells, mounts, etc.) makes you choose race, class, and appearance at the beginning of the game. Titan Quest is … spartan (pun intended).
&lt;/p&gt;
&lt;p&gt;
As with many games, as you fight, you gain equipment. Not unusual. But what is unusual is that all the equipment drops are what the monster was wearing at the time! The caveat is that equipment is often damaged during the fight, and what drops can be of lower quality than what it was wearing originally (or it could be so badly damaged it's not useful).  I'm not sure if the damage level depends on the battle.  I'm also not sure if this game mechanic adds much. The equipment also can be enhanced with “runes” (like Diablo 2), except the mechanics are different, and IMO more fun. You have two weapon sets, which allows you to play both ranged and melee, or have an alternate weapon for monsters that can resist your primary.
&lt;/p&gt;
&lt;p&gt;
What's I really liked was the class/talent system.  At every level, you gain skill points, which can be used either for advancing general knowledge of an area (a class), or for unlocking a new skill, or for improving a skill. Many skills can only be learned if you have a lot of knowledge in that area.  My initial instinct was to get a few skills and improve them a lot, so they'd be supremely powerful skills. However, the strategy guides I've read online suggest that you're better off learning the general knowledge first, and then learning the higher level skills. So this gave me an interesting tradeoff: if I learn the general knowledge (which also gives me better stats), it's delaying my gaining skills. I might have a harder time now, but the payoff is that I'll get the more powerful skills sooner. (Side note: with the expansion pack you can pay to unlearn skills.)  I've decided on a middle path: I picked a small number of skills to focus on, and spend the rest getting general knowledge.  As with many RPGs, as you add skills, you get more options of play style, not only statically (in the choice of skills) but dynamically (in choosing how to use combinations). 
&lt;/p&gt;
&lt;p&gt;
In addition to the general knowledge vs. skill choice, Titan Quest also delays the introduction of classes by tying it to the skill system.  You don't choose a class until level 2, when you have skill points, because you have to use those skill points to choose an area of study.  At level 8, after you've been playing the game for a while, you get to choose a second area of study.  So now we have over 30 class+class combinations, but you don't have to pick until you've gotten a feel for the game.
&lt;/p&gt;
&lt;p&gt;
I've been quite happy not having to make so many choices at the very beginning of the game. When I first start playing, I &lt;em&gt;don't have enough information to make that choice&lt;/em&gt;. That means I'm often going to make a bad choice. Delaying a choice not only reduces complexity as I'm learning the game, but it allows me to make better choices. I think Guild Wars and Dungeon Siege II do something similar with their class system.  Titan Quest and World of Warcraft also allow you to unlearn skills, which means you can explore more styles of play without starting over from scratch.  When penalties for making a wrong choice are reduced or eliminated, people take more risks. They explore more. They try more things, and have more fun.
&lt;/p&gt;
&lt;p&gt;
Aside from the interesting class system, I think the game is mostly like Diablo 2, down to potions and portals and “acts” and economy. This is a good thing. The graphics are incredible, looking like hand-drawn 2D art, except it's actually 3D. I've been having lots of fun. Unfortunately, I don't think I'll play through a second time. Unlike Diablo, the maps are hand-drawn and not random. This makes it more enjoyable the first time and less enjoyable on subsequent plays. Also, it requires the CD in the drive, and having to swap CDs with whatever game I get next is &lt;a href="http://simblob.blogspot.com/2006/02/polite-games.html"&gt;a &lt;strong&gt;huge&lt;/strong&gt; barrier&lt;/a&gt;. Still, I'm going to get ~50 hours of gameplay for $20, and I think that's a pretty good deal.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;sup&gt;*&lt;/sup&gt;Update:&lt;/strong&gt; [2008-07-31] Some people pointed out that there's not much “role playing” in this “role playing game”, and delaying choices may be less appropriate if it's a true role playing game.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3392978520097554979?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3392978520097554979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3392978520097554979' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3392978520097554979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3392978520097554979'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/06/titan-quest.html' title='Titan Quest'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-2316808075537622231</id><published>2008-06-10T16:37:00.000-07:00</published><updated>2011-10-17T21:08:03.634-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='ideas'/><title type='text'>Shifting Game Maps</title><content type='html'>&lt;p&gt;
Game worlds are typically quite static, with some games allowing you to change the world, and even fewer allowing changes that affect movement in significant ways. One of the ideas I wanted to explore was to have the world change significantly, but the coordinate system keep the player in a “reasonable” place even while the world was changing under him. The game idea is that you are playing the role of a tiny ship inside a giant creature. As you traverse the blood vessels and shoot the white blood cells of the immune system, the creature becomes more agitated. As its heart beats faster, ripples run down the arteries, and the entire creature may start moving about. The game becomes more difficult not because the enemies are tougher, but because the world itself is changing and becoming somewhat disorienting.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Turn on animation&lt;/strong&gt; to see some movement of the map.
&lt;/p&gt;
&lt;/p&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="500"&gt;&lt;param name="movie" value="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/corridor/corridor.swf"&gt;&lt;object type="application/x-shockwave-flash" data="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/corridor/corridor.swf" width="500" height="500"&gt;
      &lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/corridor/corridor.png" alt="(diagram showing a moving corridor for a dungeon crawl game)"&gt;&lt;br /&gt;(This is a screen shot of the Flash demo.)
&lt;/object&gt;&lt;/object&gt;
&lt;p&gt;
The &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/game-ideas/corridor/"&gt;article about the demo&lt;/a&gt; goes into more detail about the code.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-2316808075537622231?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/2316808075537622231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=2316808075537622231' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/2316808075537622231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/2316808075537622231'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/06/game-idea-shifting-game-maps.html' title='Shifting Game Maps'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-9181774539596972488</id><published>2008-02-18T15:10:00.000-08:00</published><updated>2010-09-04T08:38:33.440-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='grids'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Interactive A* Illustration</title><content type='html'>&lt;p&gt;
A few months ago, I wrote that &lt;a href="http://simblob.blogspot.com/2007/07/interactive-illustrations.html"&gt;I was working on interactive illustrations for my A* pages&lt;/a&gt;. Has it taken that long? Well, I've actually had things working for a while now. I just haven't published it. Why? It turns out that my A* pages, which I wrote a long time ago, are really out of date. As I was trying to illustrate various concepts, I was trying to illustrate the concepts from my pages, but not all of them worked well in my Flash program. I eventually realized that some of those concepts are just unimportant in practice. I also discovered that the style I used in my diagrams only works for very simple maps. Once you add terrain into the maps, the visual style fails to convey the concepts I wanted to illustrate.
&lt;/p&gt;
&lt;p&gt;
I haven't yet resolved these issues, which are taking a lot more time than writing the code itself.  The algorithm and data structure code is complete, so I've uploaded them to my web site.  You can see &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/a-star-flash/"&gt;source code&lt;/a&gt; and &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/a-star-flash/test.html"&gt;the applet running on a square grid&lt;/a&gt;. The code is released under the MIT license; feel free to use it. I made the A* portion work on any graph, and included square, hexagonal, and triangular grids. This isn't the most efficient approach, but I wanted something flexible so that I could later use it in my &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;article on grids&lt;/a&gt;. I haven't finished the hexagonal grid code yet; the only thing missing is the pixel coordinate to hex coordinate transformation.  Enjoy!
&lt;/p&gt;
&lt;p&gt;
Once I figure out the best way to display the important concepts for A*, I'll update my A* pages to use the interactive diagrams.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-9181774539596972488?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/9181774539596972488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=9181774539596972488' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/9181774539596972488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/9181774539596972488'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/02/interactive-illustration.html' title='Interactive A* Illustration'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7056693646660719157</id><published>2008-02-12T12:15:00.000-08:00</published><updated>2008-02-12T12:38:10.361-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Game Design: Decreasing costs over time</title><content type='html'>&lt;p&gt;
In World of Warcraft, the game evolves with patches released every few months. After the most recent major patch, &lt;a href="http://www.wowwiki.com/Patch_2.3"&gt;2.3&lt;/a&gt;, many areas became significantly easier, the UI became more helpful, the item rewards got better, and it took less time to “level up”. When the expansion was released, the “regular” items in the expansion areas were often better than the “elite” items in the regular areas. People who played the game in the early days sometimes comment on how easy things are now. (“When I was a kid, I had to walk uphill in the snow…”)  The question is, is this a good thing?
&lt;/p&gt;
&lt;p&gt;
I think in the context of a game like WoW, it is a good strategy.
&lt;/p&gt;
&lt;p&gt;
Players who are more skilled or have more time to play get lots of rewards, and later players who are less skilled or play less get those same rewards. It seems unfair. This happens in the tech industry too. Last year Apple released the iPhone for $600, and later lowered the price to $400. Many people were upset by this. But price drops are common in the tech industry. The iPhone will be available for $30 in five years. Does that mean nobody should buy it now? No! What you're paying for it not just the product itself, but &lt;em&gt;getting it earlier&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;
It's the same in World of Warcraft and other long-lived games. What was expensive before is cheaper now, except instead of the “cost” being in terms of money, it's in time and skill and effort. It doesn't even the playing field though. Just as the top items become available to more people, new top items are added that beat the old ones. There's a new iPhone out now. And Patch 2.4 will add new cool items for the top players to get. Those who had the top items before will find it easier to get the new items. Without these changes, I think the game would stagnate. Everyone will reach their peak potential, and there will be nothing more to get. You need change to keep the game exciting to existing players and new players, and Blizzard seems to be good at doing that.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7056693646660719157?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7056693646660719157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7056693646660719157' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7056693646660719157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7056693646660719157'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2008/02/game-design-decreasing-costs-over-time.html' title='Game Design: Decreasing costs over time'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-40920925391809740</id><published>2007-11-13T11:08:00.000-08:00</published><updated>2007-11-13T12:22:52.920-08:00</updated><title type='text'>Transport Tycoon</title><content type='html'>&lt;p&gt;
I've been playing &lt;a href="http://en.wikipedia.org/wiki/Transport_Tycoon"&gt;Transport Tycoon&lt;/a&gt; for a very long time. It's a simulation game involving transporting goods and passengers — the kind of game I love, and &lt;a href="http://www-cs-students.stanford.edu/~amitp/simblob/alternatives.html"&gt;once wanted to write&lt;/a&gt;. I started playing again early this year, with &lt;a href="http://www.openttd.org/about.php"&gt;OpenTTD&lt;/a&gt; (an open source “clone” of the game), and then got interested again once I tried their &lt;a href="http://www.openttd.org/nightly.php"&gt;nightly builds&lt;/a&gt; with lots of new features.
&lt;/p&gt;
&lt;p&gt;
The weird thing about Transport Tycoon is that the original game didn't keep my interest. The AI was horrible, and the game balance didn't work for me. It was too hard at the beginning of the game and then once you had enough money, the game was too easy.  Instead, what I and others have done is come up with our own game goals, treating it more as a “software toy” than a game. In some games I avoid making any changes to the terrain; I work within its constraints to create “natural” looking routes. Other times I challenge myself to connect every city, or handle all resources of a certain type. 
&lt;/p&gt;
&lt;p&gt;
One of my favorites is designing high capacity routes and stations. I once built a custom scenario with around 100 coal mines and a single power station, and then designed routes that could handle all the coal. OpenTTD opens up new design possibilities, with changes to track building, station size and shape, and routing algorithms (see &lt;a href="http://wiki.openttd.org/index.php/Building_signals#Pre-signals"&gt;pre-signals&lt;/a&gt; and &lt;a href="http://wiki.openttd.org/index.php/Advanced_signalling_examples"&gt;advanced signals&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;
One of the things I've been exploring recently is having multiple industries near one another. Instead of one station per coal mine, I can have lots of coal mines surrounding a high capacity station. Here's one of the stations I'm working on:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s1600-h/Tunnel+stations.png"&gt;&lt;img  style="width:90%" src="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s400/Tunnel+stations.png"  alt="Tunnel stations" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
To increase the space I have available for coal mines, I built tunnels underneath some open space, where I'll place mines.  The concrete tiles to the northeast of the station are considered station platforms, and extend the “reach” of the station. Using those as tendrils I can make the station area larger, and place more coal mines within its reach.  On the other end of the line is a large station next to a power plant; all the trains go from here (and similar coal stations) to that power plant.  You can see to the lower left that there are many tracks to handle the trains, plus extra space where I'll add more tracks after I add coal mines.  The challenges here are keeping the trains running, dealing with breakdowns, handling the capacity, and making a nice layout.
&lt;/p&gt;
&lt;p&gt;
Once I started playing with tunnels, I designed this station for passenger traffic:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoDDH-lnKI/AAAAAAAAAIQ/l3ZOzL3pBPQ/s1600-h/Superstation+40.png"&gt;&lt;img  style="width:90%" src="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoDDH-lnKI/AAAAAAAAAIQ/l3ZOzL3pBPQ/s400/Superstation+40.png" alt="40 track station" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
It looks like two stations but it's actually one. I built a longer one, then removed the tracks in the middle. The station fits into a 20x20 space, but can handle 40 trains. As shown all the trains come in from the southeast, but it's also possible to use this station with 20 tracks handling northern traffic and 20 for southern traffic, either as a through station or as a terminal.  The gap between the two blocks has to be 6 tiles, so there are 14 tiles left, meaning the trains can be at most 7 tiles (14 cars) long. I haven't actually used this station anywhere, but with the tunnels at the ends, it could be quite useful for tunneling underneath a major city.
&lt;/p&gt;
&lt;p&gt;
There are lots more interesting layouts for stations and tracks. Take a look at &lt;a href="http://openttdcoop.ppcis.org/wiki/index.php/Basic_Junctions"&gt;this guide&lt;/a&gt; and &lt;a href="http://www.tt-forums.net/viewtopic.php?f=47&amp;amp;t=33550"&gt;this forum post&lt;/a&gt; for some examples. You can do a lot with the three signal types (each having their own algorithms); the routing is the most fascinating part of this game. &lt;a href="http://openttdcoop.ppcis.org/wiki/index.php/Presignal_Bypass_Station"&gt;This experimental station&lt;/a&gt; is an example of the weird things you can express with &lt;a href="http://openttdcoop.ppcis.org/wiki/index.php/Guides:Presignals"&gt;advanced use of pre-signals&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
As OpenTTD adds more features, it opens up new possibilities for layout and routing. &lt;a href="http://wiki.openttd.org/index.php/New_Features_Since_0.5.0"&gt;Coming soon&lt;/a&gt; are building tracks on slopes (allows more compact layouts), new road stations, trams, one-way roads, new airports, new types of cargo, new scheduling options, and &lt;a href="http://wiki.openttd.org/index.php/Path_Based_Signaling"&gt;new signal algorithms&lt;/a&gt;. It's not a game for everyone, but it's definitely a game for me.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-40920925391809740?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/40920925391809740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=40920925391809740' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/40920925391809740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/40920925391809740'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/11/transport-tycoon.html' title='Transport Tycoon'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_kV9ZnGnZL7M/RzoB2H-lnJI/AAAAAAAAAII/FPPjYcufONo/s72-c/Tunnel+stations.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-3986402004245095707</id><published>2007-07-30T14:13:00.000-07:00</published><updated>2011-08-24T10:39:04.997-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Interactive illustrations</title><content type='html'>&lt;p&gt;
When I'm taking a class, or reading a textbook, or reading an article, there's &lt;em&gt;text&lt;/em&gt; that explains a topic, and sometimes &lt;em&gt;illustrations&lt;/em&gt; that help visualize the material covered in the text. Sometimes there are &lt;em&gt;diagrams&lt;/em&gt; that show things that are not in the text, and &lt;em&gt;charts&lt;/em&gt; that summarize data sets that are not included in the text. When these materials are put on the web, those illustrations, diagrams, and charts remain as they were in print: they're &lt;strong&gt;static&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
In class I often would wonder what would happen if something was changed. For example, in the programming languages course we saw a program and what would happen on the stack and heap to store data. What happens to the stack if you change the order in which you declare variables? I now know the answer to the question, but it would have been nice if I could somehow walk up to the board, change the program text, and watch the diagram of the stack update itself to reflect the change. Although in small classrooms you might be able to convince the instructor to do this, it's completely impractical in a large class to answer every student's question this way. I can't change things in textbooks or articles either.
&lt;/p&gt;
&lt;p&gt;
But now we have the web. There's the possibility of interacting with the course material. Why don't we see much of this?
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When teaching a subject, you have a set of points you want to illustrate. With an exploratory tool the student may or may not actually reach all the points you want to teach. When those points come up in an exam, the student might not be able to answer all the important questions.
&lt;li&gt;It costs much more to develop interactive material than to develop static material. It's not only the cost of development but also in design.&lt;/li&gt;
&lt;li&gt;Web technology for interactive sites (Javascript, Flash, Java) is still somewhat unpleasant and non-portable. The dominant technologies did not win for being elegant or fast or easy to use; they won for other reasons.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Web pages are still (mostly) written in the style of books and articles. This is understandable. Films were originally in the style of stage plays. It took experimentation to discover the things you can do by changing scenes, camera angles, etc. A century later, filmmakers are still experimenting, and developing new techniques (examples: showing simultaneous scenes, time lapse, bullet time, showing the same scene from different angles at different times). Web authors have experimented with frames, multiple windows, Java applets for computer algorithms, and writing entire web sites in Flash. I think there will be many more decades of experimentation.
&lt;/p&gt;
&lt;p&gt;
For many years now I've been wanting to put interactive illustrations on my site. There are concepts like &lt;a href="http://simblob.blogspot.com/2007/06/distances-on-triangular-grid.html"&gt;distance&lt;/a&gt;, movement, pathfinding (A*), scripting, grids, AI, and simulation that I'd like to illustrate. For example I used a Java applet to demonstrate &lt;a href="http://simblob.blogspot.com/2004/10/road-building-applet.html"&gt;a UI for building roads in simultation games&lt;/a&gt;. However I wasn't happy with it. It was a separate page, not integrated into an article that explained the concepts. Java was heavyweight and tricky to get working across browsers. Several authors have produced standalone A* exploration applets or applications,  but they too weren't integrated into an article. It wasn't until I saw Raigan and Mare's &lt;a href="http://www.metanetsoftware.com/technique/tutorialA.html"&gt;article about collision detection&lt;/a&gt; that I saw what I wanted. Their article uses static illustrations to demonstrate concepts &lt;em&gt;without using interactivity&lt;/em&gt;, but makes those illustrations interactive to allow the reader to explore on their own. This addresses my concerns about interactive tools not showing the student the important points. They use Flash to implement their illustrations. Flash is so lightweight that at first I didn't realize their illustrations were interactive. There's no “loading” screen and your browser doesn't slow to a crawl. I don't know how the cost of developing them though.
&lt;/p&gt;
&lt;p&gt;
I had mentioned a few months ago that &lt;a href="http://simblob.blogspot.com/2007/04/transportation-mini-game-where-is-it.html"&gt;I haven't been working on my transportation game&lt;/a&gt;. It's true, I haven't. I've continued &lt;a href="http://simblob.blogspot.com/2007/06/learning-flash-9.html"&gt;learning Flash&lt;/a&gt; but I'm working on diagrams for my site instead of a game. So far my experience has been rather positive. Flash has been easier to learn and use than I expected. The raw graphics libraries are nicer than what I had used before (&lt;a href="http://www.pygame.org/"&gt;PyGame&lt;/a&gt;, OpenGL, SVG, and &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/2d/index.html"&gt;Java2D&lt;/a&gt;); however, the user interface libraries (buttons, scrollbars, etc.) are worse than those in Java Swing. I especially like that the graphics libraries include things that are useful for illustrations: overlays, translucency, and bevel/glow/shadow effects. For example, you can draw an arrow overlay on top of the illustration without redrawing the illustration itself, or add a glow effect to the object you want the reader to pay attention to. Flash's &lt;a href="http://oddhammer.com/actionscriptperformance/set4/"&gt;performance is reasonable&lt;/a&gt;. The library reference is nice. There's a free command line compiler for people who don't want to use Adobe's fancy IDE. I'm enjoying it.
&lt;/p&gt;
&lt;p&gt;
My first project has been developing a grid library, using the algorithms from my &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;grid article&lt;/a&gt; to generate the illustrations on &lt;a href="http://theory.stanford.edu/~amitp/GameProgramming/AStarComparison.html"&gt;this page&lt;/a&gt; and &lt;a href="http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html"&gt;this page&lt;/a&gt;. The most surprising thing for me has been that the 300k of images on those pages could likely be replaced by a 10k Flash file.  So far my Flash program compiles to 6.5k, but it doesn't have a UI that lets you select various algorithms and heuristics, and it also doesn't allow you to draw your own obstacles on the grid.
&lt;/p&gt;
&lt;p&gt;
I'm going to follow the style in Raigan and Mare's collision detection tutorial: using Flash to replace static illustrations, &lt;em&gt;not&lt;/em&gt; to use Flash for the entire site. I'm also keeping the images as fallbacks for people who don't want or use Flash. Since most of the illustrations need to stand alone without user interaction, the fallback technique works well in this context. While working on the A* illustrations, I realized that my A* pages are &lt;a href="http://web.archive.org/web/*/http://theory.stanford.edu/~amitp/GameProgramming/"&gt;nearly ten years old&lt;/a&gt;, and my thoughts on the subject have changed somewhat. I'd like to go back and update them to reflect my new thinking. But first, I'm going to add interactive illustrations.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-3986402004245095707?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/3986402004245095707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=3986402004245095707' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3986402004245095707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/3986402004245095707'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/07/interactive-illustrations.html' title='Interactive illustrations'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-7396088872194198170</id><published>2007-06-29T07:46:00.000-07:00</published><updated>2010-03-25T13:52:53.185-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Learning Flash 9</title><content type='html'>&lt;p&gt;
This week I switched from Flash 8 to Flash 9.
&lt;/p&gt;
&lt;p&gt;
  Since last year I've
  been &lt;a href="http://simblob.blogspot.com/2006/12/learning-flash.html"&gt;playing
  with Flash 8&lt;/a&gt;, using the Motion-Twin command-line
  compiler &lt;code&gt;mtasc&lt;/code&gt;. I was using it to write a &lt;a href="http://simblob.blogspot.com/2007/01/transportation-mini-game-rough-design.html"&gt;transportation game&lt;/a&gt;, and I had something running and was making progress, until Supreme Commander came out. Then I went back to playing games instead of writing them.  Although I'd still like to work on that game, I've found that I also want to use Flash to build interactive demonstrations of concepts I describe on my site. For example, in my &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;article about grids&lt;/a&gt; I'd like to make those diagrams interactive so that you can better see how the coordinate systems work. Diagrams are now what I'm using to learn Flash; I may go back to the game later (or maybe not).
&lt;/p&gt;
&lt;p&gt;
  I like &lt;code&gt;mtasc&lt;/code&gt;. However, it only supports Flash 8
  (Actionscript 2), and is not going to be updated for Flash 9
  (Actionscript 3).  It's a dead end.  Flash 9 is not only
  significantly &lt;a href="http://oddhammer.com/actionscriptperformance/set4/"&gt;faster&lt;/a&gt;
  (almost as fast as Java), but it also has major changes to the
  libraries. Instead of &lt;code&gt;mtasc&lt;/code&gt;, you can
  use &lt;a href="http://haxe.org/"&gt;HaXe&lt;/a&gt;, which is a new language
  similar to Actionscript/Javascript/ECMAscript.  HaXe looks neat
  (better types, type inference), but it's a different language, not
  Actionscript. Part of my goal is to publish my source code so that
  others can use it, and it's less useful to publish code that isn't
  usable in Actionscript. It's also less useful to publish code that
  requires an expensive development environment (for example, Flex, at
  $500). And it's easier to learn a language when there are lots of other users, posting tips. So I've been staying with &lt;code&gt;mtasc&lt;/code&gt;; the same code
  works with both &lt;code&gt;mtasc&lt;/code&gt; and the Flash 8 development
  environment.
&lt;/p&gt;
&lt;p&gt;
  Last week &lt;a href="http://blog.richcollins.net/"&gt;Rich Collins&lt;/a&gt;
  pointed me to the free command-line Flash 9
  compiler, &lt;code&gt;mxmlc&lt;/code&gt;. Wonderful! It's free, it's Flash 9,
  it's command line—just what I was looking for. I spent a few days
  learning about Flash 9, and
  found &lt;a href="http://www.senocular.com/flash/tutorials/as3withmxmlc/"&gt;this
  tutorial&lt;/a&gt; and &lt;a href="http://www.kirupa.com/forum/showthread.php?s=54c7bfc3f287e5c768243146fff7f729&amp;amp;t=223798"&gt;these tips&lt;/a&gt; to be most helpful. My initial thoughts:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;(&lt;strong&gt;yay&lt;/strong&gt;) Flash 9 has much better libraries than Flash 8. The
  sprites (movieclips), the event handling, and the graphics commands
  are all nicer.&lt;/li&gt;
  &lt;li&gt;(&lt;strong&gt;boo&lt;/strong&gt;) Actionscript 3 is more verbose than Actionscript 2, with
  types, packages, &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;override&lt;/code&gt;, and
  other annotations. It's less of a scripting language and more like
  Java. This is bad.&lt;/li&gt;
  &lt;li&gt;(yay) Flash 9 is much faster than Flash 8, in part thanks to all
  those type annotations.&lt;/li&gt;
  &lt;li&gt;(boo) The &lt;code&gt;mxmlc&lt;/code&gt; compiler is significantly slower
  than &lt;code&gt;mtasc&lt;/code&gt;, in part because it's written in Java, which
  has a high startup time.&lt;/li&gt;
  &lt;li&gt;(boo) The &lt;code&gt;mxmlc&lt;/code&gt; compiler is not open source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  I've been converting some of my code from Flash 8 to Flash 9, and
  despite the increased verbosity, I've been happy with it. If you want to use
  Flash 9 with free command-line compiler, start with &lt;a href="http://www.senocular.com/flash/tutorials/as3withmxmlc/"&gt;this
  tutorial&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;Update:&lt;/strong&gt; [2007-07-28] [2010-03-25] You can download the Flash command-line compiler (Flex mxmlc) for free, without registration, &lt;a href="http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex4sdk"&gt;from Adobe&lt;/a&gt;. Once I learned the language, the &lt;a href="http://livedocs.adobe.com/flex/201/langref/"&gt;Flash 9 library reference&lt;/a&gt; became my #1 source of information.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-7396088872194198170?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/7396088872194198170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=7396088872194198170' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7396088872194198170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/7396088872194198170'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/06/learning-flash-9.html' title='Learning Flash 9'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-1173799772830394966</id><published>2007-06-19T14:07:00.001-07:00</published><updated>2007-06-19T17:53:31.349-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grids'/><category scheme='http://www.blogger.com/atom/ns#' term='triangles'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Distances on a triangular grid</title><content type='html'>&lt;p&gt;
As part of
my &lt;a 
href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;article
on grids&lt;/a&gt;, I'd like to provide basic algorithms for grids. I
already know how to compute distances on square and hexagon grids, but
I didn't know how to compute them on a triangle grid. I initially tried changing coordinate systems, inspired by &lt;a href="http://www-cs-students.stanford.edu/~amitp/Articles/Hexagon2.html"&gt;Charles Fu's coordinate system&lt;/a&gt;.  I normally use the coordinate system from my article on grids:
&lt;/p&gt;

&lt;p align="center"&gt;
  &lt;img src="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/triangle-grid-face-coordinates.png" /&gt;
&lt;/p&gt;

&lt;p&gt;
  The first coordinate (which I will call &lt;code&gt;u&lt;/code&gt;) is the
  position along the horizontal axis; the second (which I
  call &lt;code&gt;v&lt;/code&gt;) is the position along the southwest/northeast
  diagonal. The Left/Right parity introduces some compliation; I
  let &lt;code&gt;R&lt;/code&gt; be 1 and &lt;code&gt;L&lt;/code&gt; be 0.  This coordinate
  system is nice for storing maps in an array, but it's not as clean,
  because triangle grids have three axes but only two of them are
  expressed in the coordinates.  For the horizontal axis I
  used &lt;code&gt;2u+R&lt;/code&gt; as the position; for the second axis I
  used &lt;code&gt;2v+R&lt;/code&gt;. I guessed that the position along the third
  axis would &lt;code&gt;u-v&lt;/code&gt;. I drew some grids on paper, wrote down
  the &lt;code&gt;u,v&lt;/code&gt; values, and then computed the three positional
  values. They behave properly for computing distances along the
  third axis, but the system falls apart when computing distances not
  on the three axes.
&lt;/p&gt;

&lt;p&gt;
  Frustrated, I decided to step back and approach this problem in a
  more principled manner. In Charles Fu's three-axis coordinate system, taking
  one step in the grid changes two of the coordinates and leaves the
  third alone. For a triangle grid, the dominating feature is the
  straight lines in three directions. I looked on the web for any articles
  describing distances on triangular grids, but didn't find any that satisfied me. &lt;a href="http://cit.zesoi.fer.hr/downloadPaper.php?paper=435"&gt;This paper&lt;/a&gt; was promising but unfortunately gives an iterative algorithm and not a clean formula. However, it uses an interesting coordinate system, which is useful for computing distances. If you take one step in the
  grid, you will cross exactly one line.  &lt;strong&gt;The distance between
  two locations will be the number of lines you have to
  cross.&lt;/strong&gt; I wanted to use a coordinate system in which
  crossing a line changes a coordinate:
&lt;/p&gt;

&lt;p align="center"&gt;
&lt;a href="http://4.bp.blogspot.com/_kV9ZnGnZL7M/RnhFtmB3NLI/AAAAAAAAABo/etGBSKpe634/s1600-h/triangle-grid-coordinates.png"&gt;&lt;img  src="http://4.bp.blogspot.com/_kV9ZnGnZL7M/RnhFtmB3NLI/AAAAAAAAABo/etGBSKpe634/s400/triangle-grid-coordinates.png" border="0" alt="Coordinate system for triangles" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  I want to map
  the &lt;code&gt;u,v,R&lt;/code&gt; coordinates I normally use into the alternate coordinate system &lt;code&gt;a,b,c&lt;/code&gt;, where
  exactly one of &lt;code&gt;a,b,c&lt;/code&gt; changes when you cross a
  line. Here's where I decided to use algebra. In &lt;code&gt;u,v,R&lt;/code&gt; space, the black triangle has
  coordinates &lt;code&gt;0,0,0&lt;/code&gt;; the triangle to the east of it has
  coordinates &lt;code&gt;0,0,1&lt;/code&gt;; to the west, &lt;code&gt;-1,0,1&lt;/code&gt;; to
  the south, &lt;code&gt;0,-1,1&lt;/code&gt;. In &lt;code&gt;a,b,c&lt;/code&gt; space, the
  black triangle is &lt;code&gt;0,0,0&lt;/code&gt;; the east triangle
  is &lt;code&gt;0,0,1&lt;/code&gt;; the west triangle is &lt;code&gt;0,-1,0&lt;/code&gt;; and
  the south triangle is &lt;code&gt;-1,0,0&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
  I want a formula that computes &lt;code&gt;a&lt;/code&gt;, and I expect it to be
  linear, so I write &lt;code&gt;a = a&lt;sub&gt;u&lt;/sub&gt;*u + a&lt;sub&gt;v&lt;/sub&gt;*v +
  a&lt;sub&gt;R&lt;/sub&gt;*R + constant&lt;/code&gt;. That's four unknowns, but we know the
  constant will be 0, so it's really three unknowns. To get three
  equations, I plug in the values for the east, west, and south
  triangles, then solve for the coefficients. Let's see what happens:
&lt;/p&gt;

&lt;pre&gt;
  &lt;em&gt;For each s in (a, b, c), and each triangle i:&lt;/em&gt;
  s&lt;sub&gt;i&lt;/sub&gt; = s&lt;sub&gt;u&lt;/sub&gt;*u + s&lt;sub&gt;v&lt;/sub&gt;*v + s&lt;sub&gt;R&lt;/sub&gt;*R

  &lt;em&gt;East triangle:&lt;/em&gt; u,v,R = 0,0,1
  s&lt;sub&gt;1&lt;/sub&gt; = s&lt;sub&gt;u&lt;/sub&gt;*0 + s&lt;sub&gt;v&lt;/sub&gt;*0 + s&lt;sub&gt;R&lt;/sub&gt;*1
  &lt;em&gt;therefore:&lt;/em&gt; s&lt;sub&gt;R&lt;/sub&gt; = s&lt;sub&gt;1&lt;/sub&gt;
  
  &lt;em&gt;West triangle:&lt;/em&gt; u,v,R = -1,0,1
  s&lt;sub&gt;2&lt;/sub&gt; = s&lt;sub&gt;u&lt;/sub&gt;*-1 + s&lt;sub&gt;v&lt;/sub&gt;*0 + s&lt;sub&gt;R&lt;/sub&gt;*1
  &lt;em&gt;therefore:&lt;/em&gt; s&lt;sub&gt;u&lt;/sub&gt; = s&lt;sub&gt;R&lt;/sub&gt; - s&lt;sub&gt;2&lt;/sub&gt;
  
  &lt;em&gt;South triangle:&lt;/em&gt; u,v,R = 0,-1,1
  s&lt;sub&gt;3&lt;/sub&gt; = s&lt;sub&gt;u&lt;/sub&gt;*0 + s&lt;sub&gt;v&lt;/sub&gt;*-1 + s&lt;sub&gt;R&lt;/sub&gt;*1
  &lt;em&gt;therefore:&lt;/em&gt; s&lt;sub&gt;v&lt;/sub&gt; = s&lt;sub&gt;R&lt;/sub&gt; - s&lt;sub&gt;3&lt;/sub&gt;
&lt;/pre&gt;

&lt;p&gt;
  When &lt;code&gt;s&lt;/code&gt; is axis &lt;code&gt;a&lt;/code&gt;, we look
  at &lt;code&gt;a&lt;/code&gt; for triangles 1 (east), 2 (west), and 3 (south),
  so &lt;code&gt;a&lt;sub&gt;1&lt;/sub&gt;&lt;/code&gt; is 0, &lt;code&gt;a&lt;sub&gt;2&lt;/sub&gt;&lt;/code&gt; is 0,
  and &lt;code&gt;a&lt;sub&gt;3&lt;/sub&gt;&lt;/code&gt; is -1.  The algebra tells us
  that &lt;code&gt;a&lt;sub&gt;R&lt;/sub&gt;&lt;/code&gt; = 0, &lt;code&gt;a&lt;sub&gt;u&lt;/sub&gt;&lt;/code&gt; = 0,
  and &lt;code&gt;a&lt;sub&gt;v&lt;/sub&gt;&lt;/code&gt; = 1.  That means the formula
  is &lt;code&gt;a = v&lt;/code&gt;. Pretty simple. Doing the same
  for &lt;code&gt;b&lt;/code&gt; and &lt;code&gt;c&lt;/code&gt;, I get &lt;code&gt;b = u&lt;/code&gt;
  and &lt;code&gt;c = u + v + R&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
  These results are simple enough that if I played with the grid
  enough, I would have come up with them.  However the algebraic
  approach works for other constraints, not only the simple ones. I
  also used it to create a coordinate system with &lt;code&gt;2u+v+R,
  u+2v+R, v-u&lt;/code&gt; (this is 30 degrees rotated from the one above),
  which may be useful for other algorithms. Algebra and calculus also
  come in handy for defining movements (e.g., splines), growth rates,
  equilibria in interacting systems, and other types of interesting
  behaviors in games.
&lt;/p&gt;

&lt;p&gt;
  What is the distance between two locations in a triangular grid?
  Each step involves a line crossing, and we want to count steps, so
  we add up the line crossings along each axis (&lt;code&gt;a, b,
  c&lt;/code&gt;): &lt;code&gt;distance = abs(&amp;Delta;u) + abs(&amp;Delta;v) +
  abs(&amp;Delta;(u+v+R))&lt;/code&gt;. This looks just like the Manhattan distance formula, but for triangles instead of squares.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-1173799772830394966?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/1173799772830394966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=1173799772830394966' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1173799772830394966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/1173799772830394966'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/06/distances-on-triangular-grid.html' title='Distances on a triangular grid'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_kV9ZnGnZL7M/RnhFtmB3NLI/AAAAAAAAABo/etGBSKpe634/s72-c/triangle-grid-coordinates.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5865351795111716235</id><published>2007-04-14T13:57:00.000-07:00</published><updated>2007-04-14T14:31:01.554-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Transportation mini-game, where is it?</title><content type='html'>&lt;p&gt;
A few months ago I posted about a &lt;a href="http://simblob.blogspot.com/2007/01/transportation-mini-game-rough-design.html"&gt;transportation mini-game I had started&lt;/a&gt;. What happened to it?
&lt;/p&gt;
&lt;p&gt;
I've been a bit distracted and haven't worked on it much. I did learn some Flash, and posted about &lt;a href="http://simblob.blogspot.com/2006/12/learning-flash.html"&gt;command line tools for Flash&lt;/a&gt;, and then I went to the Game Developer's Conference, which made me think about what kind of game I was working on.
&lt;/p&gt;
&lt;p&gt;
The first comparison that came to mind was &lt;a href="http://en.wikipedia.org/wiki/Lemmings_%28video_game%29"&gt;Lemmings&lt;/a&gt;.  In Lemmings, a stream of lemmings is coming into the world, and your goal is to give a few lemmings a job. Jobs include digging through the ground, floating through the air, building steps, turning other lemmings around, etc. The lemmings with jobs affect how the rest of the lemmings move through the world. In the transportation mini-game, there is a stream of packages coming into the warehouse and your goal is to direct them to their goal. You place objects like conveyor belts to change the flow of packages. As with lemming jobs, there are a variety of objects you can use. However you don't use the packages themselves to do this, and there's no terrain to modify.
&lt;/p&gt;
&lt;p&gt;
More recently I ran across a series of “tower defense” games, in which a stream of monsters is walking by and your goal is to shoot them. Just as there are many types of lemming jobs, there are a variety of guns that you can place on towers. The most interesting of these games is &lt;a href="http://www.handdrawngames.com/DesktopTD/"&gt;Desktop TD&lt;/a&gt;, in which the monsters have to walk around the towers you build. This adds a layer of strategy: &lt;em&gt;where&lt;/em&gt; you place your towers matters a great deal because if affects how the monsters walk around them, and where the monsters walk affects where your towers should be. In &lt;a href="http://www.youtube.com/watch?v=7QdAU4o7NZ4"&gt;this YouTube video&lt;/a&gt;, you can see an example of how you can arrange towers into a maze to force the monsters to take a convoluted path to their goal:
&lt;/p&gt;
&lt;p&gt;
&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7QdAU4o7NZ4"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/7QdAU4o7NZ4" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;
Desktop TD is a lot of fun. It combines a building game with a shooting game. The monsters have a pathfinding algorithm controlling them, and you have to think about how your buildings will affect the results of that algorithm. You also have to think about different kinds of monsters, different kinds of towers, and whether to upgrade existing towers or build new ones.
&lt;/p&gt;
&lt;/p&gt;
Unfortunately after playing it for &lt;em&gt;many, many hours&lt;/em&gt; it made me less interested in my transportation mini-game. It satisfied my desire to play a game with flowing objects. I'd still like to work on this game but I've been busy with other projects and don't know when I'll get back to it. Maybe someone working on a tower defense clone will incorporate aspects of the transportation mini-game instead, and then I can spend many hours playing their game. &lt;tt&gt;;)&lt;/tt&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5865351795111716235?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5865351795111716235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5865351795111716235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5865351795111716235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5865351795111716235'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/04/transportation-mini-game-where-is-it.html' title='Transportation mini-game, where is it?'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6747498608229952630</id><published>2007-03-05T22:42:00.000-08:00</published><updated>2007-03-05T22:57:33.111-08:00</updated><title type='text'>Game Developer's Conference</title><content type='html'>&lt;p&gt;
Despite the talk of GDC 2007 becoming more and more like E3, I'm going to go to GDC this year. I'm interested in the Wii, DS, mobile games, online games, and web games, as well as graphics, music, sound effects, design, algorithms, and storytelling. I'm interested in just about everything but business/legal aspects; I expect that working on games will remain just a hobby for me.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6747498608229952630?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6747498608229952630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6747498608229952630' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6747498608229952630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6747498608229952630'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/03/game-developers-conference.html' title='Game Developer&apos;s Conference'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6227485586194561182</id><published>2007-02-07T21:28:00.000-08:00</published><updated>2009-01-10T19:17:03.072-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Silverfall Demo</title><content type='html'>&lt;p&gt;
I've been playing the demo of &lt;a href="http://www.silverfall-game.com/en/"&gt;Silverfall&lt;/a&gt; (see the &lt;a href="http://pc.ign.com/objects/791/791205.html"&gt;preview on IGN&lt;/a&gt;). Like Dungeon Siege and Titan Quest, Silverfall reminds me of Diablo 2, which I loved.  It's a role-playing game in which your character goes on quests, fights monsters, collects treasures, upgrade items, learn new skills, etc.  The graphics are great, or would be, if my computer was fast enough. Some of the more interesting things about it:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Graphics&lt;/strong&gt;. The characters are surrounded by a black outline. See &lt;a href="http://media.pc.ign.com/media/791/791205/img_3986018.html"&gt;this screenshot (and others) on IGN&lt;/a&gt;. It reminds me of cartoons, where the outlines help separate the important characters from the backgrounds. It's more than this though. Silverfall's graphics look &lt;em&gt;hand drawn&lt;/em&gt;, at every angle and zoom. I can't figure out how they did this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Physics&lt;/strong&gt;. It can take advantage of a physics accelerator card. I didn't see much that would benefit from physics though, and it's sort of annoying to have to install a physics library.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI&lt;/strong&gt;. The UI is really smooth compared to Dungeon Siege, although not quite as nice as Diablo 2 for reasons I'll list below. The use of the mouse and hotkeys is nice.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Factions&lt;/strong&gt;. The nice twist on this type of game is Nature vs. Technology. When you complete or reject certain quests, you gain favor with either nature or technology (these are diametrically opposed). When your favor with either faction increases, you gain access to better items and skills. Also, in the story your faction becomes stronger, which changes the storyline and the appearance and buildings in the city. A third path is to favor neither side, accepting quests on behalf of both. This gives you more experience from quests, but you no longer have access to the special items from each faction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quests&lt;/strong&gt;. A consequence of the nature vs. technology factions is that some quests will make you worse off. In most RPGs, the more quests you do, the better. But here, the quests can hurt your standing with one of the factions, and you can lose access to items, skills, and further quests. So you need to think about which quests you accept.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skill Tree&lt;/strong&gt;. Like Guild Wars and unlike Diablo, you can change your skills, at a cost. I think this increases the enjoyment of the game the first time through, because you can try out several approaches without starting over, but it may decrease enjoyment the next time through the game. It's a good tradeoff though, because it helps a large number of casual players at the expense of a small number of dedicated players.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Classes&lt;/strong&gt;. There are races but no character classes. Instead, you can choose your skills to build your own style of character. There are skills for melee, ranged weapons, light magic, dark magic, faction (nature or technology), and your race (human, goblins, trolls, elves). This yields a large set of styles of play. I tried one which combined melee and dark magic, and a different style that combined light magic and nature skills.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
It seems silly, but I think the black outlines and the hand-drawn look of the characters and other objects are a sign of something important. Before 3d accelerator cards, graphics were drawn by programmers and artists, and games had lots of different visual styles. With 3d cards, a certain style supported by the card is cheap, fast, and easy.  All other styles are more expensive, slower, and harder to program.  This has led to a far less diverse set of visual styles. &lt;a href="http://www.gamespot.com/ps2/action/okami/review.html"&gt;Okami&lt;/a&gt; is a rare exception. (Side note: I'm not sure how the Silverfall developers implemented their outlines. At first I thought it'd be a single pass over the buffer to look for differences in Z values, but when you zoom in you can see the outlines are at the vector level, not the pixel level, so it's possibly a shader that looks for normals perpendicular to the screen. And I have no clue how they made everything look hand-drawn.)  In old-style art, &lt;em&gt;it was easy to identify objects&lt;/em&gt;. You could tell what was clickable, what was a button, where a person was, etc. Artists weren't looking for realism. They wanted to express concepts and emotions and ideas in game art. Newer games tend to be cluttered. Just look at how much harder it is to see all the objects in &lt;a href="http://en.wikipedia.org/wiki/Image:Sims2_photo.png"&gt;The Sims 2&lt;/a&gt; vs. &lt;a href="http://en.wikipedia.org/wiki/Image:TheSims.jpg"&gt;The Sims 1&lt;/a&gt;.  Newer games are &lt;a href="http://www.scottmccloud.com/inventions/triangle/triangle.html"&gt;more realistic, but less artistic&lt;/a&gt;.  The harder it is to see what's on the screen, the more effort the player makes in &lt;em&gt;seeing&lt;/em&gt; things, and the less effort the player can make in &lt;em&gt;deciding&lt;/em&gt; things. Although there are games like Quake and Halo where much of the challenge really is in seeing things, I don't think RPG and strategy games fall into that category. I like games where the challenge isn't in seeing the objects on the screen, but in deciding what to do. I hope the shaders in graphics cards enable game developers to explore more visual styles.
&lt;/p&gt;
&lt;p&gt;
Since I'm on the subject of displaying information for players, there are several things that Silverfall seemed to get wrong:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Camera rotation&lt;/strong&gt;. I spent &lt;em&gt;way&lt;/em&gt; too much time rotating the camera in Silverfall (and Dungeon Siege). I spent no time doing this in Diablo. Does rotating the camera add to the game? &lt;strong&gt;No&lt;/strong&gt;, I don't think it does. Yes, it's “cool” and people seem to expect it, but it didn't make the game better. In fact, it made it worse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zoom&lt;/strong&gt;. You can zoom in to see your character close up. The character looks really nice when zoomed in. But this mode is useless when actually playing the game. For playing, you want to be zoomed out as much as possible. (In fact I'd like to zoom out even farther than Silverfall allows.) This means that all the effort to make the zoomed-in camera work (for example, distant objects, level-of-detail terrain, and expensive high-resolution texture art) is a waste. Unfortunately you need some of this to put on the box so people will buy your game. But it's a big waste.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loading zones&lt;/strong&gt;. When you travel from one zone to another, the game stops and loads the next zone. That's a minor annoyance. The big problem is that &lt;em&gt;all your spells are cancelled&lt;/em&gt;.  Techniques for &lt;a href="http://www.drizzle.com/~scottb/gdc/continuous-world.htm"&gt;avoiding loading screens are well-known&lt;/a&gt;. I don't mind if there's loading when you enter a tunnel or cave or dungeon. It's when you see arbitrary boundaries unrelated to the game that it becomes annoying.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Terrain&lt;/strong&gt;. The demo takes place in a swampy region. The terrain is very bumpy. It looks like it was randomly generated (maybe Perlin noise?). The small problem is that the random-looking terrain adds nothing to the gameplay. It just gets in the way. The &lt;em&gt;big&lt;/em&gt; problem is that the slopes that are walkable and the slopes that are not at &lt;em&gt;not distinguished in any way&lt;/em&gt;, except by clicking and finding that your character doesn't move. At the very least the cursor should change color or shape to indicate that some area isn't accessible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Map&lt;/strong&gt;. This is actually a complaint about lots of games. If I were Indiana Jones and I had to go to 3 places to collect artifacts, &lt;strong&gt;I'm going to mark those 3 places on my map&lt;/strong&gt;.  Far too many games have a notion of an “active” quest, and only show that &lt;em&gt;one&lt;/em&gt; place on the map.  &lt;strong&gt;No!&lt;/strong&gt;  Make the map work like I would actually use it.  Show me &lt;em&gt;all&lt;/em&gt; the important places I need to keep track of.  Let me add markers. Let me add notes. Let me draw lines. Don't make me keep a second map on paper because your map is so lame.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quest Listing&lt;/strong&gt;. There are some bugs in the Silverfall quest list, which I'm sure they'll fix before release. For example, it doesn't remember where you were the last time you brought up the list. A bigger problem though is that the quests do not keep track of who assigned the quest (and where). I found myself often re-reading quest descriptions, trying to guess who would have assigned such a quest. Some of them are on the map and some are not. Some of them trigger the rewards automatically and some do not. It's a mess. Just as with maps, the quest listing should match what I would do on paper. I would keep track of who gave the quest, where I need to go, and what the potential rewards are (especially related to faction). I would allow adding notes, assigning priorities, and sorting the list. For example, there was one quest I received that I was not ready to do. I'd like to move it to the end or otherwise mark it as “later” so that it doesn't clutter up the list of active quests I want to work on. And if the map shows all quests, it should also use different markers for active and postponed quests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trees&lt;/strong&gt;. I've saved my biggest complaint for last. The graphics in Silverfall are great. I admit that. The problem is that the swampy area has lots of trees. In the default zoomed-out view, the canopy of trees blocks your view. So the game very helpfully hides the leaves. In addition, tree trunks block your view. So the game very helpfully hides the trees near your character. But tree trunks still &lt;em&gt;block your attacks&lt;/em&gt;. So you now have a completely mysterious and maddening situation in which &lt;em&gt;invisible objects block your attacks&lt;/em&gt;. Your attacks are blocked and you can't see why. This is truly bad. Just get rid of all the trees. They don't add anything to the game. Alternatively, since it's unlikely the developers will do that at this point, just let me walk and attack through the trees.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I really liked the demo of Silverfall.  It's really promising and it could be lots of fun, except there are some little (easily fixed) things that really detract from the experience.  Even with the flaws, the demo was more fun than most other games I've tried. I hope the developers read this post and fix these problems before release. (Oh, and if you're reading this: lose the cheesy box cover art.)
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6227485586194561182?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6227485586194561182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6227485586194561182' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6227485586194561182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6227485586194561182'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/02/silverfall-demo.html' title='Silverfall Demo'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-5818937576685185715</id><published>2007-01-02T14:31:00.000-08:00</published><updated>2009-01-10T19:17:58.913-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Transportation mini-game, rough design</title><content type='html'>&lt;p&gt;
About a year ago I decided to &lt;a href="http://simblob.blogspot.com/2006/02/change-of-direction.html"&gt;stop working on Simblob&lt;/a&gt;, and started working on a &lt;a href="http://simblob.blogspot.com/2006/02/rough-sketch-for-transportation-game.html"&gt;transportation game&lt;/a&gt; (more about the design &lt;a href="http://simblob.blogspot.com/2006/02/transportation-game-basic-objects.html"&gt;here&lt;/a&gt; and &lt;a href="http://simblob.blogspot.com/2006/03/transportation-game-models.html"&gt;here&lt;/a&gt;).  My progress has been rather slow, in part because I keep playing other games instead of writing one.
&lt;/p&gt;
&lt;p&gt;
One of the components of the transportation game is the &lt;strong&gt;Warehouse&lt;/strong&gt;.  If you view your transportation network as a graph, the Warehouse is an internal node, the Supplies and Sinks are the endpoints, and the transport types (trucks, ships, trains) are the links.  The Warehouse is a key component of your transportation system.  Goods come in and goods go out.  Sometimes goods are stored, repackaged, relabeled, inspected, and assembled.  In the network, Warehouses can be used as:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Buffers&lt;/strong&gt;.  Goods come in, a stored for a time, and then go out.  The time the goods are supplied is earlier than the time they are needed.  For example, it may take several months to produce the toys that will be bought in the Christmas shopping season; those toys need to be stored somewhere until shoppers are ready to buy them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Switches&lt;/strong&gt;.  Goods come in from several sources and go out to several sources.  For example, a grocery store chain may have supplies coming in from farms, ranches, orchards, etc., and may have those same goods go out to several neighborhood stores.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Caches&lt;/strong&gt;.  Goods aren't needed all the time, and their demand is unpredictable, but when the demand is there, the customers want the goods right away.  The solution is to keep some near the customers, so that when they need some, they can get it quickly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transformer&lt;/strong&gt;.  Goods arrive in one condition but leave in a better condition.  For example, a Warehouse may add tracking, labeling, and pricing information to the goods before sending them on to stores.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplexing&lt;/strong&gt;.  Goods arrive in large shipments from suppliers, but each store needs a small amount of each good.  The Warehouse can repackage the goods into smaller units.  For example, an electronics retailer may receive a truck full of VCRs, a truck full of TVs, and a truck full of speakers, and the Warehouse can reshuffle these into three trucks, each with VCRs, TVs, and speakers.  That way only one truck has to be sent to each retail store.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Warehouses are an interesting enough part of this game that I decided to try making a mini-game out of them.
&lt;/p&gt;
&lt;p&gt;
In the mini-game, the goals (switching, multiplexing, etc.) are given to you, and your job is to design the warehouse to meet those goals.  Goods come in from the left and exit on the right.  There are multiple types of goods, each represented by a color (or shape).  Your job is to get the goods from the left to the right, while achieving your goals.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RZrhG85201I/AAAAAAAAAAM/j-FznWxD_1c/s1600-h/crossboxx-sketch-1.jpg"&gt;&lt;img  src="http://2.bp.blogspot.com/_kV9ZnGnZL7M/RZrhG85201I/AAAAAAAAAAM/j-FznWxD_1c/s800/crossboxx-sketch-1.jpg" alt="&amp;quot;napkin&amp;quot; sketch of warehouse mini-game" style="border:1px dashed gray" id="BLOGGER_PHOTO_ID_5015568644574729042" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The warehouse is laid out on a grid.  The basic component is a conveyor belt, which takes up 1 grid space.  The conveyor belt pieces are linked into a chain that defines the flow of goods through the warehouse.  What makes the game interesting (I hope) is the special pieces you can add to the conveyor belt.  A &lt;em&gt;color filter&lt;/em&gt; only allows a certain color to pass.  With it you can separate a mixed flow into separate products.  Similarly, a &lt;em&gt;shape filter&lt;/em&gt; only allows a certain shape to pass (I may end up combining shape and color filters into one).  A &lt;em&gt;counter filter&lt;/em&gt; has a counter, and only allows an object to pass when the counter reaches a particular value.  For example, a 3-counter filter will allow every third object to pass.  These filters are used to separate a stream of objects into smaller streams.  Note that a 1-counter is the same as a regular conveyor belt; it filters nothing.  A &lt;em&gt;mixer&lt;/em&gt; mixes objects from multiple streams, in some proportion.  For example, a mixer can be set to take 1 green circle and 2 purple triangles, and the resulting stream will have twice as many purple triangles as green circles.  A &lt;em&gt;packer&lt;/em&gt; takes multiple objects and packs them into a single object of a different type; an &lt;em&gt;unpacker&lt;/em&gt; takes a single object and unpacks it into multiple objects.  A &lt;em&gt;carousel&lt;/em&gt; stores objects, up to its capacity, until the output stream(s) have space for unloading objects.  It can be used to even out a highly variable flow.  There are more objects I can imagine: shelves, aisles, employees, forklifts, labelers, inventory trackers, etc.
&lt;/p&gt;
&lt;p&gt;
The game involves a series of levels of increasing difficulty.  Each level has a grid, some supplies, some demands, some parts to use to construct the conveyor belt network, and some goals to meet.  The grid may have objects on it already, which cannot be moved.
&lt;/p&gt;
&lt;p&gt;
At each time step, all goods (objects) move one space, according to the rules of flow:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The conveyor belt defines the directions the object can move.&lt;/li&gt;
&lt;li&gt;An object cannot move in the direction of an incompatible filter.&lt;/li&gt;
&lt;li&gt;An object cannot move to a spot that has an object, unless that object is about to move.&lt;/li&gt;
&lt;li&gt;Of all directions available to move, the object chooses one at random.&lt;/li&gt;
&lt;li&gt;If a box cannot move, it sits still. If it sits still too long, it breaks.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
If you think about these rules hard enough, you'll see that they may be difficult to implement.  In particular, rule #3 says that an object can move if another object can move.  And that object too may be subject to this rule, leading to an entire chain of dependencies that have to be solved.  I have an algorithm partially designed but I'm not yet convinced my algorithm will work; if it does not, I'll revise the rules.
&lt;/p&gt;
&lt;p&gt;
The puzzles I'm less sure about, but here's what I've been thinking about:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Slow packers&lt;/strong&gt;. Split the incoming supplies into several streams so that you can have several packers handling them, then coming the streams into one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Irregular supplies&lt;/strong&gt;. Demand is steady. Build a large buffer so that you can handle supplies being late.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multiplexing&lt;/strong&gt;. As described in the electronics retailer example, suppliers send large shipments of a single product type. Build buffers so that you'll have enough of each product type. Unpack the large supplies into small ones, mix the goods together, pack them into shipments that get sent to retailers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bad supply&lt;/strong&gt;. Some of the incoming goods are faulty. The supplier will lower quality as much as he can get away with. It's too expensive to check everything, but if you check nothing, the quality will keep going down. Check some of the goods to keep quality high enough to satisfy customers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Time, quantity, quality, costs, and profit can all be part of the goals.  For example, incoming goods might cost $4/box, and outgoing goods might bring in $5/box.  Each box you send through the system gives you $1 in profit.  If a box breaks (due to sitting on the conveyor belt for too long), you lose the $4.  You might be willing to have a less reliable system to keep costs down, or you may want to make it more reliable to minimize losses.
&lt;/p&gt;
&lt;p&gt;
At this point the design is only on paper.  I plan to create a prototype soon to try to judge how fun or interesting the game might be.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-5818937576685185715?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/5818937576685185715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=5818937576685185715' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5818937576685185715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/5818937576685185715'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2007/01/transportation-mini-game-rough-design.html' title='Transportation mini-game, rough design'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_kV9ZnGnZL7M/RZrhG85201I/AAAAAAAAAAM/j-FznWxD_1c/s72-c/crossboxx-sketch-1.jpg' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-4386333476435439925</id><published>2006-12-31T16:17:00.000-08:00</published><updated>2006-12-31T16:29:02.312-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Choosing algorithms</title><content type='html'>&lt;p&gt;
Game developers can't always find their algorithms in an algorithms textbook.  Academic algorithms tend to be general purpose and often aren't the best choice for games.  For example, compare &lt;a href="http://www.cambridgeincolour.com/tutorials/image-interpolation.htm"&gt;textbook image scaling algorithms&lt;/a&gt; to &lt;a href="http://www.hiend3d.com/hq4x.html"&gt;hq4x&lt;/a&gt;.  Hq4x is very impressive!  How could the textbooks have missed it?  It's because it's not &lt;em&gt;general purpose&lt;/em&gt;.  It is designed to work on hand-drawn low-color sprite graphics in games, whereas the textbook algorithms work on all sorts of images.  Another example is path-finding algorithms.  Dijkstra's algorithm is a general-purpose algorithm; A* came out of AI research (which is slightly closer to game programming) and is a little more specialized. But there are plenty of techniques used in games that aren't found in the textbooks. They take advantage of game-specific knowledge: the structure of maps, the characteristics of moving units, etc.
&lt;/p&gt;
&lt;p&gt;
The general purpose algorithms are a good place to start but don't limit yourself to them. There might be a specialized algorithm that works better for your problem, or it may be worth the effort to design your own algorithm.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-4386333476435439925?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/4386333476435439925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=4386333476435439925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4386333476435439925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/4386333476435439925'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/12/choosing-algorithms.html' title='Choosing algorithms'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6242262591549338671</id><published>2006-12-25T23:15:00.000-08:00</published><updated>2006-12-26T13:58:43.375-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Water in strategy games</title><content type='html'>&lt;p&gt;
In just about every city-building strategy game out there, water is static. It doesn't flow; it doesn't affect much; it doesn't change with seasons; and you can't change it.  In 1994, I started the &lt;a href="http://www-cs-students.stanford.edu/~amitp/games.html"&gt;Simblob project&lt;/a&gt; to experiment with water flow in games, among other things.  You could build canals and dams and dikes, divert waterways, and flood the opponent's cities.  Well, you would've been able to if I had ever gotten around to implementing the opponent. The problem was that playing with water was &lt;em&gt;way too much fun!&lt;/em&gt;  I implemented heavy rains, droughts, floods, sedimentation, and erosion.  Playing the game was lots of fun too, even though there was very little “game” actually implemented.  In the end all I had done was work on graphics and water simulation, and I decided to stop working on it and start something else.
&lt;/p&gt;
&lt;div style="float:right;width:370px;height:370px;margin:1em"&gt;
&lt;img width="350" height="350" src="http://www-cs-students.stanford.edu/~amitp/simblob/blob-game-rivers.png" /&gt;
&lt;/div&gt;
&lt;p&gt;
I still think water simulation has enormous potential for a strategy game. Imagine diverting your opponent's main source of water, so his crops fail and his people revolt. Or an enemy operative damaging your main dam, and you scrambling to repair it before it breaks, destroying your cities. Water is incredibly important in real cities, and it should be important in building-based strategy games.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.playten.com/eng/development.php?page=49&amp;amp;view=18"&gt;Battle for Atlantis&lt;/a&gt; is a strategy game coming out in 2007 that has water simulation. Here's a quote from their web site:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
For the first time in the history of RTS, a full physical model of water space will be created. The water has stopped being a “dead area” – a non-interactive flat mirror good only ship sailing. Real waves and tsunamis, flood and destruction of the landscape by water, river flows and waterfalls, splendid underwater effects – all this gives an enormous scope of creation and makes the game world of Atlantis as real as never before.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
It sounds promising!  &lt;a href="http://www.3dgamers.com/screenshots/games/dayatlantis/"&gt;3dgamers&lt;/a&gt; has some screenshots.  I just hope the water simulation is used more for gameplay than for graphical effects.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6242262591549338671?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6242262591549338671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6242262591549338671' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6242262591549338671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6242262591549338671'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/12/water-in-strategy-games.html' title='Water in strategy games'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-895202213115177700</id><published>2006-12-24T11:01:00.000-08:00</published><updated>2009-01-10T19:18:21.174-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Learning Flash 8</title><content type='html'>&lt;p&gt;
Back in 2004, &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-flash.html"&gt;I attempted to learn Flash programming, but failed to find free tools&lt;/a&gt;, and ended up &lt;a href="http://simblob.blogspot.com/2004/10/road-building-applet.html"&gt;writing Java applets instead&lt;/a&gt;.  I was &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-java.html"&gt;unhappy with Java&lt;/a&gt; for a number of reasons, but the main one was that Java applets are clunky on web pages compared to Flash objects, and as a result more people have Flash than Java.  A few months ago &lt;a href="http://troygilbert.com/"&gt;Troy Gilbert&lt;/a&gt; pointed me at &lt;a href="http://osflash.org/"&gt;OSFlash.org&lt;/a&gt;, which has a list of open source Flash development tools (thanks Troy!).  I eventually found the free and fast &lt;a href="http://www.mtasc.org/"&gt;Motion-Twin ActionScript compiler&lt;/a&gt; (&lt;code&gt;mtasc&lt;/code&gt;), but had a lot of trouble using it.  The tutorials I found on the web for Flash development assume you're using the Macromedia development environment, which I'm not, so they weren't much help. I finally figured out what I was doing wrong.
&lt;/p&gt;
&lt;p&gt;
I'm used to a certain development model: you write a program, (optionally) compile it, then run it. This might be considered “old school” by people writing Windows and Mac apps.  When writing Windows and Mac apps, you put the source code with various resources (icons, graphics, music, dialog boxes, etc.) into a “project”, which gets compiled into an executable.  In the “old” style of development (used for C++, Java, Python, Perl, Basic, Ruby, etc.), your program reads in resources after you run it. That's how I've been writing my games.  Flash seems to follow the “new” style of development, in which lots of resources, not only source code, get combined into one package.
&lt;/p&gt;
&lt;p&gt;
The open source &lt;code&gt;mtasc&lt;/code&gt; compiler only compiles Flash (ActionScript) source code. It does not handle the resources that have to be assembled into a compiled Flash file (SWF). The &lt;code&gt;mtasc&lt;/code&gt; tool will compile your source code and update a SWF file with the compiled code, but you can't use &lt;code&gt;mtasc&lt;/code&gt; to create SWF files; they have to exist already.  For that, you normally use the (commercial) Flash development environment from Macromedia. If you want to fully work in an open source world, you need another way to assemble resources. The &lt;a href="http://swfmill.org/"&gt;&lt;code&gt;swfmill&lt;/code&gt;&lt;/a&gt; tool can do this: it converts an XML file listing resources into a SWF file. With &lt;code&gt;swfmill&lt;/code&gt; my toolset is complete.
&lt;/p&gt;
&lt;p&gt;
The other thing that's confusing (for me) about Flash development is that it seems to be designed around movies, and every Flash program has a “frame rate”, even if it's not a movie. For now I'm ignoring this and just setting a low frame rate.
&lt;/p&gt;
&lt;p&gt;
The summary of what I've learned so far about open source Flash development:
&lt;/p&gt;
&lt;ol class=spaced&gt;
&lt;li&gt;Create an XML file that describes the resources you need. I'm using the example XML file in &lt;a href="http://swfmill.org/doc/using-swfmill.html"&gt;Mark Winterhalder's well-written tutorial&lt;/a&gt; on the &lt;code&gt;swfmill&lt;/code&gt; site:
&lt;pre class=snippet&gt;
&amp;lt;?xml version="1.0" encoding="iso-8859-1" ?&amp;gt;

&amp;lt;movie width="320" height="240" framerate="12"&amp;gt;
  &amp;lt;background color="#ffffff"/&amp;gt;
  &amp;lt;frame/&amp;gt;
&amp;lt;/movie&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Compile the XML file into an SWF file:
&lt;pre class=snippet&gt;
swfmill simple example.xml example.swf
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create an ActionScript file with your script. I'm using an example I found on the &lt;code&gt;mtasc&lt;/code&gt; site:
&lt;pre class=snippet&gt;
class prototypes {
    static var app : prototypes;

    function prototypes() {
        // creates a 'tf' TextField size 320,200 at pos 0,0
        _root.createTextField("tf",0,0,0,320,200);
        // write some text into it
        _root.tf.text = "Hello world !";
    }

    static function main(mc) {
        app = new prototypes();
    }
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Compile the ActionScript into your existing SWF file, using the &lt;kbd&gt;-main&lt;/kbd&gt; flag to have it automatically call the &lt;code&gt;main()&lt;/code&gt; function:
&lt;pre class=snippet&gt;
mtasc example.as -swf example.swf -main
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Embed the SWF into a web page using the &lt;kbd&gt;&amp;lt;embed&amp;gt;&lt;/kbd&gt; tag, as described on the &lt;a href="http://haxe.org/tutos/start/flash"&gt;haXe&lt;/a&gt; site:
&lt;pre class=snippet&gt;
&amp;lt;html&amp;gt;
&amp;lt;body bgcolor="#cccccc"&amp;gt;
&amp;lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
  width="320" height="200" id="test"&amp;gt;
&amp;lt;param name="movie" value="example.swf" /&amp;gt;
&amp;lt;embed src="example.swf" width="320" height="200" 
  name="test" type="application/x-shockwave-flash"
  pluginspage="http://www.macromedia.com/go/getflashplayer"
/&amp;gt;
&amp;lt;/object&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;See the results in a browser. Hooray!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
For me, getting started is the hardest step. Once I have something running, development becomes easier. Now that I have a Flash program running, my next steps are to set up my development environment, then learn about the Flash libraries. I've been wanting to learn Flash programming for a long time, but I kept getting stuck. I'm quite glad I finally put the pieces together, and I hope the above description helps others get started.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-895202213115177700?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/895202213115177700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=895202213115177700' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/895202213115177700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/895202213115177700'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/12/learning-flash.html' title='Learning Flash 8'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-6842169742105839101</id><published>2006-12-17T22:35:00.001-08:00</published><updated>2006-12-17T22:35:29.287-08:00</updated><title type='text'>Software pricing</title><content type='html'>&lt;p&gt;
(Warning: this post doesn't have a point; it's just me thinking aloud.)
&lt;/p&gt;
&lt;p&gt;
Most products have some fixed costs and some marginal costs of production. The fixed cost would be the factory; the marginal cost would be the labor, materials, transportation, packaging, marketing, etc.  The price of the product usually starts out high, and competition brings it down over time to be close to the marginal cost (at least according to economic theory). 
&lt;/p&gt;
&lt;p&gt;
Creative products like music, novels, and movies typically have high fixed costs and low marginal costs.  As technology has improved, the marginal cost of music, novels, and movies has gone down close to zero, and we now have a great deal of piracy.  Software is similar to music, novels, and music, except that the marginal cost has been close to zero for a very long time, and the software industry has had to deal with the problem of piracy for longer.  Economic theory suggests with good competition, the price of these products should eventually go down close to the marginal cost.  For all of these products, the sellers have tied the product you really want (for example, a song) to something physical (a CD), and the physical object has a non-zero marginal cost.  However, with electronic distribution, people want the music without paying for the CD, the movie without a DVD, a novel without a book, and software without the installation CDs and manuals.  The marginal cost of distribution is close to zero, so in theory, the price should eventually get to zero.
&lt;/p&gt;
&lt;p&gt;
The open source community sometimes argues that the price of software should be zero (to match the marginal cost), and that developers can earn money selling services and support.  There's a major problem with this: the incentives are completely messed up. If a developer makes more money when more support is needed, there's an incentive to make the product require more support. Products will end up harder to use and contain less documentation.  There's also no strong incentive to offer new features for free, because you're not getting paid for new versions of the software.
&lt;/p&gt;
&lt;p&gt;
With MMORPGs we're seeing a lot of experimentation with software pricing. This is possible because the software is virtually useless without connecting to the service. World of Warcraft charges for the software plus for the service. They crack down on people who want to offer their own service (alternate free servers) because they make most of their money from the service they offer, and don't want competition. World of Warcraft also charges for expansions (which are rare). With Guild Wars the software is free (you can download it from their site for free), but &lt;em&gt;access&lt;/em&gt; to different services (areas of the world) costs a fixed fee. Those services do not carry a monthly fee. With ArchLord the software costs money but there's no monthly fee. Second Life (which isn't technically a game) makes money both by renting areas of the virtual world and by selling virtual currency, which you can use to buy in-game goods and services. Games can also make money by selling in-game items, upgrades, status, etc. MMORPGs can tie the game to the service, and then charge for the service. However they are not making their software open source, because they do not want competitors to create compatible services.
&lt;/p&gt;
&lt;p&gt;
Most games however do not have the option of charging for services, and it is difficult to charge for support in a consumer-level product (consumers get angry and feel that they deserve free support). So game developers are stuck with piracy, just like makers of music and movies. We want to recover the high fixed cost of developing the product, so we charge for the software, even though the marginal cost is close to zero. Consumers are more willing to buy software that comes in a physical package, so we include a box, installation CD, a manual, etc., all of which reduces sales and profits. Alas.
&lt;/p&gt;
&lt;p&gt;
There is one more thing we might want to explore. Music, games, movies, etc., are all emotional experiences, and they're &lt;em&gt;worth more to people&lt;/em&gt; when the emotions are greater. One way this works with music is to use concerts, association with movies or TV shows, branded products associated with the band, and other sorts of tie-ins. With movies, the same movie is worth more when people go watch it together at the theatre than when they watch it alone years later on network TV. A novel is more valuable when your reading club is reading it right now and you want to participate in their discussions. These products are more valuable &lt;em&gt;at certain times&lt;/em&gt; than at others. Watching a TV show the night it airs is more valuable because I can talk to my friends about it; watching it later (with TiVo) is less valuable. What can we do with games? I think the fan sites are a big help. Frequent updates and developer involvement in forums can help too. The Movies let users upload their creations (not their games) to the site. The Sims lets you download objects created by others. Even in a single player game, you can offer something that lets people connect to each other. When they're sharing an experience, it will have more emotional value. And that is something that could reduce piracy—you're not just buying a game; you're buying access to a community.
&lt;/p&gt;
&lt;p&gt;
I think piracy will always be with us, but I think the open source model is unlikely to work for games. Charging for support gives a perverse incentives to developers to make things work badly or confusingly. Charging for service might work for some types of games, and the MMORPG developers seem to be exploring the options. I think the way to approach the problem is what many game developers already do partially without realizing it: offer multiple experiences at different prices. Offer a free demo that has a substantial part of the game and no support; this matches the marginal cost of the software alone. Offer the full version without annoying copy protection (why do so many developers make their paying customers get a worse game than the pirates get??). Make a ”special edition” that appeals to the least price sensitive and most rabid fans. Offer special products (t-shirts, trinkets, etc.) that tie in to the game. Make a community site that people actually like (so that they don't go to other sites for the information they want), and make all or some of it open only to people who bought the game. Make sure the developers are involved with the community site. Change the model from selling software to selling enjoyment. Look at other businesses that do this (amusement parks, movie theatres); they sell the basic product at a lower cost and then sell extras (such as food and drinks) for a much higher price than the marginal cost of those extras.  Price-sensitive customers get annoyed by this, but it works for the business because they're not just paying for a drink; they're paying extra for the enjoyment of the drink in that location.
&lt;/p&gt;
&lt;p&gt;
We need to consider the entire experience of playing a game, not only the software, as a potential source of revenue, and then figure out how to best recover the high fixed costs of making the game, and also allow for a low marginal price so that we can get a large audience. We need to consider that games don't need to be played in isolation; people talking about a game with their friends or even with strangers can add to the experience. We need to consider that different people are willing to pay different amounts for the experience. It's the entire experience we're selling, not just a box with software.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-6842169742105839101?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/6842169742105839101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=6842169742105839101' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6842169742105839101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/6842169742105839101'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/12/software-pricing.html' title='Software pricing'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-696179770773403605</id><published>2006-12-16T18:40:00.000-08:00</published><updated>2009-01-10T19:19:01.070-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Rules of Algebra fail with floats</title><content type='html'>&lt;p&gt;
One thing to be careful about when programming games is relying on the rules of algebra.  Simple laws like the Associative Law and Distributive Law don't always work when using floating point numbers.  I'll give some Python code to demonstrate, but these problems are with floats, not with Python.
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Distributive Law&lt;/strong&gt;. We've been taught that &lt;kbd&gt;a * (b + c) == (a * b) + (a * c)&lt;/kbd&gt;.
&lt;pre class=snippet&gt;
a, b, c = 0.111, 0.201, 0.305
s1 = a * (b + c)
s2 = (a * b) + (a * c)
print '%.08f - %.08f = %.08f' % (s1, s2, s1 - s2)
print '  equal? %s' % (s1 == s2)
&lt;/pre&gt;
&lt;p&gt;
These are the results:
&lt;/p&gt;
&lt;pre&gt;
0.05616600 - 0.05616600 = -0.00000000
  equal? False
&lt;/pre&gt;
&lt;p&gt;
The difference looks like 0, but it's not. The two sums are not equal. To see the problem, change the format specifier &lt;code&gt;%.08f&lt;/code&gt; to &lt;code&gt;%g&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Associative Law&lt;/strong&gt;. We've been taught that &lt;kbd&gt;a + (b + c) == (a + b) + c&lt;/kbd&gt;.  When some of those are negative and some are positive (and occasionally even when they're all positive), the results won't be the same.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Additive Inverse&lt;/strong&gt;. We've been taught that &lt;kbd&gt;a + b - b == a&lt;/kbd&gt;.
&lt;pre class=snippet&gt;
a = 1e-30
b = 1e+30
print a, a + b - b, (a + b - b) == a
&lt;/pre&gt;
&lt;p&gt;
The result is that &lt;kbd&gt;(a + b - b) != a&lt;/kbd&gt;. You can look at this example as a special case of the Associative Law.
&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;
To some of you these problems will seem obvious and not a big deal for most applications. Why do I bring it up in this blog? Loss of precision can open up exploits in multiplayer games. Let's consider a game in which you can trade with someone else, and the total amount of money is represented as a float. If player A has a large amount of money &lt;kbd&gt;a&lt;/kbd&gt;, he may be able to send a very small amount &lt;kbd&gt;x&lt;/kbd&gt; to B (who has &lt;kbd&gt;b&lt;/kbd&gt;) without it affecting his own amount. We can have &lt;kbd&gt;a + b &amp;lt; (a - x) + (b + x)&lt;/kbd&gt;, which means this exploit creates new money out of nowhere.
&lt;/p&gt;
&lt;p&gt;
If you're using floating point numbers, be sure to use double precision.  Alternatively, use integers or fixed point arithmetic to avoid some of these issues. If you do a lot of math in your game, be sure to learn about numerical programming. There are a &lt;em&gt;lot&lt;/em&gt; more issues than the simple ones I describe here.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-696179770773403605?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/696179770773403605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=696179770773403605' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/696179770773403605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/696179770773403605'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/12/rules-of-algebra-fail-with-floats.html' title='Rules of Algebra fail with floats'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-116397526196133788</id><published>2006-11-19T14:26:00.000-08:00</published><updated>2006-11-19T14:27:41.976-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Using oscillation to speed learning</title><content type='html'>&lt;p&gt;
I've been reading &lt;a href="http://faculty.ed.uiuc.edu/g-cziko/wm/"&gt;Without Miracles&lt;/a&gt;. I had just read about children learning labels. The example was a child looking at a bird and then being told it was called a "bird", then looking at a different bird and being told it was a "bird". The child then has to generalize and consider that other small flying creatures are likely to be "birds" as well. However, upon seeing a butterfly and being told it was not a bird, the child then has to refine his understanding of what a "bird" is.
&lt;/p&gt;
&lt;p&gt;
This form of learning, with overgeneralization followed by correction, may well be faster than undergeneralizing. For example, what would happen if the child only believed the two creatures he saw were birds, and did not label other small flying creatures as birds until explicitly told they were birds?  He'd learn slower.
&lt;/p&gt;
&lt;p&gt;
I was at the beach, looking at tide pools, when I realized there's a similarity to the child's learning. Rivers flow in one direction (usually) and have a certain amount of life in them. Beaches have water flowing in both directions, due to waves (short time scale), tides (medium time scale), and seasons (long time scale). The diversity of life in tide pools is far greater than what I've seen in rivers. 
&lt;/p&gt;
&lt;p&gt;
In the case of the child's learning, generalization (classifying everything as a bird) is one direction and correction (being told that some creatures previously thought to be birds are not) is the other direction.  Could it be that &lt;strong&gt;oscillation&lt;/strong&gt; leads to faster "learning" than a steady stream?
&lt;/p&gt;
&lt;p&gt;
The advantage of learning and then correcting mistakes is that you can learn faster than if you were learning cautiously enough to avoid making mistakes.  Many AI algorithms are of the cautious sort.  It may be that it'd be better to have our games learn patterns very quickly and then keep a set of exceptions.  For example, in Simulated Annealing, we slowly lower the temperature until the system stabilizes. It may be better to quickly lower the temperature, then raise it again, and continue oscillating for some time. In Neural Networks we change the neuron parameters very slowly. It may be better to change them quickly, then change them back if needed.
&lt;/p&gt;
&lt;p&gt;
I'm enjoying the book a great deal but I haven't yet figured out how I might use this for my own games. My intuition tells me that there's something very useful here, but I haven't pinpointed anything specific.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-116397526196133788?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/116397526196133788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=116397526196133788' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/116397526196133788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/116397526196133788'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/11/using-oscillation-to-speed-learning.html' title='Using oscillation to speed learning'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-116266478999968070</id><published>2006-11-04T10:25:00.000-08:00</published><updated>2006-11-04T10:26:30.023-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>The Guild 2</title><content type='html'>&lt;p&gt;
Yesterday I took a look at the &lt;a href="http://www.gamespot.com/pc/strategy/theguild2/"&gt;demo for The Guild 2&lt;/a&gt;.  It's a strange game.  It's somewhat like The Sims in that you have a character that has relationships with other people in the game, and you can start a family.  It's somewhat like a role playing game in that you have classes, skills, abilities, attributes, experience points, combat, etc.  It's somewhat like a city-building strategy game in that you can build mines, businesses, houses, and so on.  The graphics and music are nice.  The world feels alive—there are people wandering around, with jobs and relationships and government positions and alliances and feuds. While standing around, a random person came up to me and gave me a cake.  I'm very impressed with the game world.
&lt;/p&gt;
&lt;p&gt;
The problem is that someone forgot to design a &lt;em&gt;fun game&lt;/em&gt;.  In trying to do lots of different styles of games, it does none of them well.
&lt;/p&gt;
&lt;p&gt;
The game is rather tedious.  You have to keep track of your relationships with everyone else. These seem to be influenced by your position in society, your family, your religion, who you work for, and who works for you.   It has more detail than The Sims (for example, you can buy objects and give them as gifts to someone) and more relationships to keep track of than in Tropico.  The problem is that there's too much information, and you can't &lt;em&gt;act&lt;/em&gt; on most of it.  You only indirectly influence it.  This is something that is impressive and thus appealing to game designers, but it's not actually any fun.
&lt;/p&gt;
&lt;p&gt;
To run a business, you have to click on your cart, send it to the market, buy raw materials (prices are set by supply and demand) by dragging them into your cart, then send the cart back to your shop, drag the materials from the cart to the shop's inventory, click on an employee, and tell him to make an item.  Then you wait for a while, and once the item is ready, you drag the item to the cart, send the cart to the market, and drag the item to the market stall to sell it (prices are set by supply and demand).  It's impressive, but it's boring.  Imagine if Warcraft had done this—you'd have to tell each orc to walk to the mine, pick up a tool, mine for metal, pick up the metal, carry it back to the storehouse, and then walk back to the mine.  You have to do this for each business you run in The Guild 2.  Although there is a way to set this on auto-pilot, there never should've been this much detail.  The programmers wasted too much time with this.
&lt;/p&gt;
&lt;p&gt;
There's also combat, positions in government, bribery, assassinations, thievery, a legal system (including court cases), and lots more complexity to this game.  That's the real problem: there's too much to keep track of and do, and too little reward for doing it.  You get to play out the drudgery of living as a serf in the Middle Ages.  I can't even describe how bad the UI is.
&lt;/p&gt;
&lt;p&gt;
There are also some amusing things in the game.  Every building has a name: Better Homes, Lumpy &amp;amp; Liquid, The Hot Spot, Raw Iron Raw Power, A Waste of Paint, Roof Included, The Funny Farm.  The help text is often strange:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
... Scholars are also not adverse to compliments and gifts and will even let themselves be persuaded to dance.
&lt;/p&gt;
&lt;p&gt;
Once the initial awkwardness has faded one can oft soften a reluctant scholar with soft embraces and gentle kisses, bewitch him in private conversation or even climb into a tub with him. But beware of using too much imagination in your courting, for scholars seldom appreciate variety.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
There are odd player skills: Master of manure, Pack mule, Kama Sutra master, Exploiter, Great preacher, Deep sleep, Local club president, Face of innocence, Dorian Grayish.  The description for the "Strong hair growth" skill starts out like this:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
You have been blessed by nature with a curious biological phenomenon: whenever you must rot in the dungeon because of some misdeed, your hair begins to grow at a breathtaking speed.  After a few hours, you look as though you have been mouldering for 30 years.  ...
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Even though the game doesn't look like it'll be any fun for most people, I do recommend that game developers try out the demo.  Look for things that you might think would be cool in a game: multiple genres (from role playing to real time strategy to business simulation to action/combat), deep and complex simulation (relationships, businesses, employment, politics, law), open-endedness, etc.  Try to figure out whether they are actually fun for a player or merely impressive to a developer. I would have loved to design and write a game like this. It's so impressive that it's sad to see that it's not at all fun.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-116266478999968070?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/116266478999968070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=116266478999968070' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/116266478999968070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/116266478999968070'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/11/guild-2.html' title='The Guild 2'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115790355369308370</id><published>2006-09-10T08:43:00.000-07:00</published><updated>2006-09-10T09:25:36.036-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>World of Warcraft Analyses</title><content type='html'>&lt;p&gt;
The &lt;a href="http://blogs.parc.com/playon/playon.html"&gt;PlayOn&lt;/a&gt; project at Xeroc PARC has been &lt;a href="http://blogs.parc.com/playon/archives/2005/05/collecting_data.html"&gt;analyzing WoW data&lt;/a&gt; and then posting it on their &lt;a href="http://blogs.parc.com/playon/"&gt;blog&lt;/a&gt;.  (These people get to play games at work!)  Thanks to &lt;a href="http://del.icio.us/richardt"&gt;&lt;tt&gt;richardt&lt;/tt&gt;&lt;/a&gt; for the link.  Some findings I found interesting:
&lt;/p&gt;
&lt;p&gt;
They computed the fraction of time each class joins a group. As you might expect, Priest was in &lt;a href="http://blogs.parc.com/playon/archives/2005/06/grouping_ratio.html"&gt;a group much more often than any other class&lt;/a&gt;.  Priests also &lt;a href="http://blogs.parc.com/playon/archives/2005/07/leveling_time_b.html"&gt;level up faster than other classes&lt;/a&gt;.  But that seems to be an anomaly.  In general, &lt;a href="http://blogs.parc.com/playon/archives/2005/06/grouping_and_le.html"&gt;people in groups level more slowly&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
People are &lt;a href="http://blogs.parc.com/playon/archives/2005/06/level_distribut.html"&gt;more likely to be at a level that's a multiple of 10&lt;/a&gt;, probably because there are certain rewards at levels that are multiples of 10, or there are penalties (such not being able to play on lower-level Battlegrounds).  So people at a level just before those levels will &lt;a href="http://blogs.parc.com/playon/archives/2005/06/playing_time_1.html"&gt;play extra hard&lt;/a&gt; and people at those levels will try to avoid leveling.  Leveling time in general is &lt;a href="http://blogs.parc.com/playon/archives/2005/07/leveling_time.html"&gt;roughly proportional to the level&lt;/a&gt;, so you get a quadratic effect. There's a spike at level 40, most likely because that's when you can buy a mount.
&lt;/p&gt;
&lt;p&gt;
Warriors are &lt;a href="http://blogs.parc.com/playon/archives/2005/06/class_abandonme.html"&gt;the most popular class at low levels&lt;/a&gt;.  Hunters are the most popular class at high levels.  Shamans are the least popular class.  Humans are &lt;a href="http://blogs.parc.com/playon/archives/2005/06/server_sample_r.html"&gt;the most popular race&lt;/a&gt;.  Orcs are the least popular race, despite them having the best dance moves.
&lt;/p&gt;
&lt;p&gt;
It's a fun blog to read.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115790355369308370?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115790355369308370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115790355369308370' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115790355369308370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115790355369308370'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/09/world-of-warcraft-analyses.html' title='World of Warcraft Analyses'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115344475912110175</id><published>2006-07-20T18:17:00.000-07:00</published><updated>2006-07-20T18:29:02.226-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Ruby scares me</title><content type='html'>&lt;p&gt;
Every time I take a look at Ruby, I am simultaneously intrigued and disgusted.  Today I was looking at it once again, pondering the &lt;a href="http://code.whytheluckystiff.net/markaby/"&gt;Camping&lt;/a&gt; framework for writing web apps, and ran across this explanation of how it works:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
Behind the scenes, Camping actually reads its own source file (with the __FILE__ handle) and does a search and replace on all instances of Camping. It then evals the result and runs your app with the modified code!
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&amp;mdash; from &lt;a href="http://www.oreillynet.com/ruby/blog/2006/06/wild_and_crazy_metaprogramming.html"&gt;O'Reilly's Ruby column&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Argh!!&lt;/strong&gt;  On one hand, I feel like I shouldn't need to care how something is implemented. But I see this sort of thing (building and &lt;code&gt;eval&lt;/code&gt;ing code) so often in Ruby that it makes me worry that the language is incapable of expressing the abstractions that people actually want to build, and it might also be incapable of expressing the things &lt;em&gt;I&lt;/em&gt; want to build.  I guess I grew up treating &lt;code&gt;eval&lt;/code&gt; as something to use only as a last resort.  The only place I felt okay using &lt;code&gt;eval&lt;/code&gt; was Scheme, where it took program trees instead of strings.  Ruby still intrigues me though, so I'll probably try a project in Ruby at some point.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115344475912110175?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115344475912110175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115344475912110175' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115344475912110175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115344475912110175'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/07/ruby-scares-me.html' title='Ruby scares me'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115271818236815271</id><published>2006-07-12T08:25:00.000-07:00</published><updated>2006-07-21T20:24:12.763-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>An old classic: Settlers II</title><content type='html'>&lt;p&gt;
Settlers II has been remade for its 10th anniversary.  I've tried out the demo and it reminded me of all the things I liked about Settlers.  The game is somewhat unusual.  It's a building+war game, like Age of Empires, Tropico, Command &amp;amp; Conquer, etc., but its emphasis is on building and not on war.
&lt;/p&gt;
&lt;p&gt;
One of the unusual features is the transportation model. In most games of this sort, people walk around wherever they need to go, and you can build roads to speed up their movement. In Settlers, you &lt;em&gt;must&lt;/em&gt; build roads, and every &lt;em&gt;road segment&lt;/em&gt; has a settler assigned to it. That settler will move goods back and forth along the road. You have to carefully plan your roads to handle the traffic; roads can become bottlenecks. Making road segments long means you use up fewer settlers and allows faster travel; making them short means you get a higher capacity. Roads also become paved and can have donkeys to increase capacity.
&lt;/p&gt;
&lt;p&gt;
The transportation model changes the implementation strategy for the game. Usually you run a pathfinder (like A*) for each of the peasants, and combine that with a movement algorithm to avoid local obstacles. This can get expensive when you have lots of peasants. Each peasant handles a single type of good, usually assigned by you. For example, you might assign a peasant to be a miner; the pathfinder will find a path between the mine and the warehouse. There is no further distribution of goods; it goes into a global store that can be accessed instantaneously from anywhere.  In Settlers, the peasants are &lt;strong&gt;not using the pathfinder&lt;/strong&gt;.  Instead, the pathfinder is used for materials and goods.  They are physical objects that have locations and can move around. They can be put in a warehouse, but they have to be moved to the location where they get used. The peasants and road segments serve as capacity restrictions. If a good needs to move from one place to another and the road it needs to travel on is &amp;ldquo;full&amp;rdquo;, it waits for the road segment (and associated peasant) to free up.  This works somewhat like a packet-switched computer network.
&lt;/p&gt;
&lt;p&gt;
How do the goods &amp;ldquo;decide&amp;rdquo; where to go?   A local approach would be to make each good perform pathfinding to its destination.  Pathfinding on the road graph will be &lt;em&gt;much&lt;/em&gt; faster than pathfinding on a grid, because there are &lt;em&gt;far&lt;/em&gt; fewer segments and connection points.  But how do they find their destinations?  We could either keep a list of points that require certain goods, or we could build an influence map.  It's possible with an influence map to not even need pathfinding. I'm not sure what Settlers actually does.
&lt;/p&gt;
&lt;p&gt;
Another difference between Settlers and other building games is that the Settlers economy has much longer chains of production. Forests can be cut to produce wood. Wood are milled into wooden boards. Boards are used to build farms and other buildings. Farmland is used to raise crops, yielding grain. Grain is milled into flour. Wells produce water. Flour plus water is baked into bread. Grain plus water is turned into beer. Fishermen use fishing poles to catch fish. Hunters use spears to catch animals. Animals taken to the slaughterhouse become meat. Meat, fish, and bread are fed to miners. Miners can mine for coal, iron, granite, and gold. Coal and iron can be smelted into steel. Steel is taken to the metalworks to make tools such as spears, and to the armory to make swords and shields. Granite is turned into stone. Stone is used to make new types of buildings. Gold is turned into gold coins. Gold coins, swords, and shields are given to soldiers. Soldiers are needed at watchtowers, which expand your territory. The economy is complex.
&lt;/p&gt;
&lt;p&gt;
Also unlike other building games, you don't control any of your people directly. You can indirectly control them by building things. To go to war, you need soldiers, but you never explicitly recruit or place soldiers; they are produced whenever you have enough of the needed goods (gold, beer, sword, shield). You can influence what gets transported by choosing a transportation priority for each type of good (this is like QoS for TCP/IP), and you can set the priority of having soldiers vs. builders.
&lt;/p&gt;
&lt;p&gt;
At the start of the game, you don't need to worry about the full economy. For example, you can't build tools without steel, which requires coal and iron, which requires miners, which requires bread and meat, which requires grain and water and animals, which requires flour, which requires farms, which requires wooden boards, which requires wood. Instead, your initial warehouse includes many types of goods, from which you can jumpstart your economy. You don't need to make rarely used items like tools until later in the game, when your settlement is large. It's a nice way to gradually introduce complexity to the player.
&lt;/p&gt;
&lt;p&gt;
It would be nice to be able to see general trends, like whether I'm building up more bread than I need, or whether people are perpetually low on water.  It's hard to manage everything in your head by checking manually.  If I were in charge of a town like that, I'd hire some people to gather information and alert me when something's wrong. Overall though it's a very interesting game, and not like other games I've played, so I think it's worth exploring.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt;: [2006-07-21] Sören M points me to a design document about &lt;a href="http://www.s.kth.se/sigra/widelands-economy-documents/transport-system.html"&gt;transportation in Widelands&lt;/a&gt; (a game much like Settlers II).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115271818236815271?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115271818236815271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115271818236815271' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115271818236815271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115271818236815271'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/07/old-classic-settlers-ii.html' title='An old classic: Settlers II'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115248650299398755</id><published>2006-07-09T15:35:00.000-07:00</published><updated>2006-07-10T09:10:29.573-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>A Tale in the Desert 3: First Impressions</title><content type='html'>&lt;p&gt;
A Tale in the Desert is a rather odd game. It's a MMORPG based in ancient Egypt. There aren't any monsters to fight. Instead, you perform tasks like gathering, mining, farming, weaving, fishing, and so on. You use the materials you gather to make equipment, which you can use to make more complex materials and objects. Eventually you can build sculptures, buildings, and monuments. The game has a story to it, with a beginning, middle, and end. You and everyone else in the game is part of that story. The ending depends on the actions of all the players.
&lt;/p&gt;
&lt;p&gt;
It's quite different from anything else I've seen. Although games like World of Warcraft have gathering and crafting tasks, the focus there is combat, whereas in this game, it's all about gathering, crafting, building, trading, and socializing. The tasks you need to perform can depend on what others have done. For example, you may need to build something larger than what anyone else nearby has built. Once you build it, your object remains in the world, visible to everyone. As I wandered around the game world, almost every object I saw was something created by a player. As a new player, I needed to find areas that weren't already occupied, so that I could set up the equipment I needed. Some of the basic resources (wood, sand, mud, grass, stone, etc.) are shared, so it helps if you set up a workspace away from others. As far as I can tell though, workspaces have a short lifespan, so you work in an area for a while and then move on.
&lt;/p&gt;
&lt;p&gt;
The tasks you need to perform can also depend on other players. For example, you may need to build an sculpture and leave it out in the open so that passers-by can vote on whether it's attractive or an eyesore. Or you may need to talk to people and convince them of some cause. Or you may need to get people to join your guild. The social aspect is important; other people aren't there only to help you fight monsters. There's also the ability to propose new laws and get signatures/votes; if the new law gets passed, the game developers will implement it (remember LambdaMOO?). I didn't explore that aspect of the game. 
&lt;/p&gt;
&lt;p&gt;
The graphics aren't great, although they didn't bother me much. There's very little sound or music, and that hurts the game a great deal. Sound effects are incredibly important. The UI is awful. It looks like it was designed by programmers: there's lots of abstraction and generality, like scrollbars, arbitrarily sized dialogs, deep menu hierarchies, and an attempt to make everything vague so that it's reusable in other contexts. For example, to dry out grass and turn it into straw, you need to Drop the grass. This is &amp;ldquo;cool&amp;rdquo; in that it reuses an existing function, but I think the UI would be better with the task explicitly listed. The UI also offers very little feedback about objects and actions. There are lots of objects around. Some are usable and some are not. You won't know until you click and get a menu. There are lots of places where you can't do something, but it won't tell you that you can't until &lt;em&gt;after&lt;/em&gt; you've attempted to do it. For example, when planting flax seeds, it allowed me to plant a second seed too close to the first, &lt;em&gt;then&lt;/em&gt; it told me it was too close. Mark the area in red or something to give people early feedback about whether their actions are going to succeed. Don't let me do something that's not allowed.
&lt;/p&gt;
&lt;p&gt;
Another problem with the UI, at least for a beginner like me, is that it doesn't really give you any hints about what to do. There's a huge list of tasks, but no way to learn how to perform them. For example, I was supposed to learn Carpentry. How should I do that? I have no idea. There's no tutorial as far as I can tell. I ended up going to the web and searching for the information. How was I to know that I should find the "SArch" building (whatever that stands for) and click on it?
&lt;/p&gt;
&lt;p&gt;
I played for several hours and got through the ~30 starter tasks, with a lot of help from the web. That opened up new possibilities of projects I could do. However the game felt rather tedious and uninspiring. Let's see... I need 100 bricks. I'll collect mud, straw, and sand, then stand around for 10 minutes making bricks. Boring. There's no challenge in that. It's not interesting. It's likely that the social aspect makes up for it (the crowd I talked to was much friendlier and more mature than in any other game I've been in), but I didn't stick around long enough to find out.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115248650299398755?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115248650299398755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115248650299398755' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115248650299398755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115248650299398755'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/07/tale-in-desert-3-first-impressions.html' title='A Tale in the Desert 3: First Impressions'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115198482918897571</id><published>2006-07-03T20:38:00.000-07:00</published><updated>2006-07-04T09:02:30.010-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>World of Warcraft: First Impressions</title><content type='html'>&lt;p&gt;
I've been playing World of Warcraft (WoW).  It's &lt;em&gt;the&lt;/em&gt; MMORPG to try.  Last year I played around 250 hours of Guild Wars, but it's not really an MMORPG; it's somewhat like Diablo 2, which is multiplayer, but not massively so.
&lt;/p&gt;
&lt;p&gt;
To get a good feel for WoW, I played over 50 hours over the past 10 days.  I tried out 6 of 8 &lt;a href="http://www.worldofwarcraft.com/info/races/"&gt;races&lt;/a&gt; (Alliance: Human, Night Elf, Gnome, Dwarf; Horde: Troll, Tauren), 6 of 8 &lt;a href="http://www.worldofwarcraft.com/info/classes/"&gt;character classes&lt;/a&gt; (Druid, Hunter, Paladin, Rogue, Warlock, Warrior), 4 of 12 &lt;a href="http://www.worldofwarcraft.com/info/professions/"&gt;professions&lt;/a&gt; (Mining, Skinning, Cooking, Fishing), and 1 talent (Marksmanship).  I visited all 6 major cities (Stormwind, IronForge, Darnassus, Ogrimmar, Thunder Bluff, Undercity) and 3 of 4 Goblin cities (Ratchet, Gadgetzan, Booty Bay).  I played mostly PvE, but also tried out PvP, both out in the open and in 1 of the 3 PvP instances (&lt;a href="http://www.worldofwarcraft.com/pvp/battlegrounds/info-warsong.html"&gt;Warsong Gulch&lt;/a&gt;).  I visited 1 of 36 PvE &amp;ldquo;instances&amp;rdquo; (Ragefire Chasm) and 12 of 40 major regions on the &lt;a href="http://www.worldofwar.net/cartography/"&gt;map&lt;/a&gt; (The Barrens, Durotar, Mulgore, Thousand Needles, Dun Morogh, Elwynn Forest, Westfall, Redridge Mountains, Teldrassil, Stranglethorn Vale, Tirisfal Glades, Darkshore).  I tried out 1 minor quest from 2 special events (Midsummer Festival and Scourge Invasion).
&lt;/p&gt;
&lt;p&gt;
Overall, I thought the game was well done. It's &lt;em&gt;much&lt;/em&gt; more complex than Guild Wars and there are lots of different styles of play.  &lt;a href="http://en.wikipedia.org/wiki/Guild_Wars"&gt;Guild Wars&lt;/a&gt; offers character classes plus secondary classes, giving essentially 15 different combinations, although the choice of which class is primary and which is secondary gives each of those combinations two styles.  WoW offers 40 combinations of races and classes.  The races affect your appearance and give you bonuses and skills; the classes affect your clothing and give you bonuses and skills.  Within each character, Guild Wars offers 4 attributes and plenty of skills influenced by those attributes; WoW offers attributes but also 3 talent trees and plenty of skills influenced by them.  In Guild Wars, the attributes can be changed to suit each mission or area; thus, you don't have to choose which to specialize in.  In WoW, attributes are influenced by race and class, but can be modified by items and spells.  The talents are permanent choices, and thus you treat them like races and classes, and have 120 combinations of races, classes, and talents.  So already WoW has a much richer set of choices (&amp;ldquo;builds&amp;rdquo;) in characters.  But wait, there's more!  In WoW, you also have professions, which are non-combat activities, such as Skinning (get leather or other materials from animals), Leatherworking (to turn leather into items), and Enchanting (to add magic to items).  As you use the skill, you become more proficient in it, and that allows you to do more things with it (for example, when you are better at Skinning, you can skin from higher level animals).  You can choose 2 of 9 main professions, plus up to 3 side professions.  This raises the combinations of character builds to 4320, although in practice, only around 14 of the 36 combinations of professions make sense, so there are a &amp;ldquo;mere&amp;rdquo; 1680 character builds you might want to play.  In Guild Wars, your weapon choices are largely determined by your character class.  In WoW, they're influenced by class but you can learn to use new types of weapons.  There are 16 types of weapons (such as Swords, Wands, Bows, etc.), and each character class starts out knowing some of them, and can learn up to 4 to 15 of them (varies by class).  Once you choose a weapon, it increases the number of character builds to nearly 12,000.  Compare that to 15 in Guild Wars and you'll get a sense of how rich this game is.  I barely scratched the surface with what I tried out.
&lt;/p&gt;
&lt;p&gt;
Each race has a starting location in the world.  There are 8 races and 6 starting locations.  This greatly increases replay value.  In Guild Wars, there's one place everyone starts and explores, so the second time through you're not seeing anything new.  In WoW, you can play 6 times and see brand new scenery each time.  The WoW world is huge, varied, and non-linear; Guild Wars in contrast is fairly linear, much smaller, and has 5 types of areas (pre-Searing, post-Searing, jungle, desert, volcano).  Different areas have monsters of different levels, so you can't venture in to the higher level areas without being killed.  With several of my characters I did however manage to sneak by some monsters and get to high level areas, where one hit from a monster would kill me.  There are special areas called instances.  These are areas that are separate for each group of people playing.  In Guild Wars, all areas other than the cities are instances; in WoW, most areas are not, so you can see lots of other people doing things unrelated to your party's actions (seeing other people is fun!).
&lt;/p&gt;
&lt;p&gt;
There's just so much to do in World of Warcraft, and so many styles of play, that it's no wonder people spend huge amounts of time playing.  There are also lots of repetitive actions that lead to variable results; this activates the gambling portions of the brain.  For example, when performing quests to retrieve items, you will sometimes get the item and sometimes not; when killing monsters, you will sometimes get treasure and sometimes not; when fishing, you will sometimes get l fish (which can be eaten to gain health) and sometimes you will get treasure; when improving skills sometimes you will gain a skill point and sometimes not.  Everything you do works this way; it's no wonder it's addictive.
&lt;/p&gt;
&lt;p&gt;
The game was pretty smooth when it ran.  Several times though the realm I was on would be down, and I couldn't log on.  When I was on though everything was smooth and (as far as I could tell) bug-free.  Blizzard seems to be pretty good at this.
&lt;/p&gt;
&lt;p&gt;
I enjoyed the game but in the end I wasn't addicted to it (despite playing 50+ hours in 10 days).  The main problem I saw was that the reward was far too low for the amount of time I spent.  &lt;em&gt;Running from place to place&lt;/em&gt; is really time consuming.  At higher levels you can buy creatures to ride on, and this lowers travel time, but the reward is &lt;em&gt;less pain&lt;/em&gt; rather than something rewarding in its own right.
&lt;/p&gt;
&lt;p&gt;
The quests were often repetitive and boring.  For example, I had a quest to go kill some ostrich-like monsters.  It took a while to run out to that location and kill them.  When I got back to town, I got a small reward and then was told to go out and kill some lions.  I had to go back to the same area I was just in, kill lions, and go back.  I was then told to kill some dinosaurs.  I had to go back to the same area I was just in, kill dinosaurs, and go back.  After that the series of hunting quests continued in a slightly different location with slightly different animals (zebras, more lions, more birds, and more dinosaurs).  There were probably at least 15 quests like this.  Another line of quests involved killing some variant of kobold, going back to town, then being told to kill a different variant of kobold in that same area, then going back to town, then being told to kill yet another variant of kobold in the same area.  These kinds of quests really stretch out gameplay, because you have to run back and forth every time; you can't get get the next quest until you've finished the previous one.  Occasionally the quest would be more interesting (for example, collecting dinosaur eggs while killing the dinosaurs), but it only seemed slightly interesting because the quests were boring.
&lt;/p&gt;
&lt;p&gt;
I do like the whimsy in the game.  There are lots of &lt;a href="http://en.wikipedia.org/wiki/Pop_culture_references_in_World_of_Warcraft"&gt;cultural references&lt;/a&gt;, silly items, etc.  The &lt;a href="http://www.worldofwarcraft.com/info/races/dancing.html"&gt;dances&lt;/a&gt; are fun (for example, the orcs dance like MC Hammer).  The graphics look cartoony, making the game feel more fun and less serious.
&lt;/p&gt;
&lt;p&gt;
With the trial account I played, I couldn't participate in some of the interesting aspects of the game, like the auction system.  In Guild Wars, you have to wander around, asking people for things to buy or sell.  It's chaotic and it was so much of a pain, I rarely traded with anyone.  With the WoW auction system, I think I would trade much more.  Comparing trading in the two games really demonstrates how important efficient markets are.  I also couldn't really get involved in guilds, which are apparently a lot of fun (but have high time requirements).
&lt;/p&gt;
&lt;p&gt;
On my last day, I sold all my items and found that I had earned around 2.6 gold (26,000 copper pieces).  This amount of wealth was unimaginable to me a few days earlier.  The scale of wealth seems to go up exponentially.  For example, a bag that can hold 8 items costs 4 times as much as a bag that can hold 6 items.  Small increases in power come at a large increase in price.  I think this is a good game design, but it felt strange to me.  Despite getting so much, the last few days were just not much fun.  Since I had only a short time left before my trial account was cancelled, I decided to kill off my main character in a most spectacular way.  I went to the top of Thunder Bluff, the highest cliff I had found in the game, set myself on fire, and jumped off, to my death.
&lt;/p&gt;
&lt;p&gt;
It's a very interesting and rich game.  It's just not for me.  It takes too much time and wasn't rewarding enough. If I were paying the monthly fee, I would feel like I had to play a lot to get my money's worth, and I'd end up playing even when it wasn't fun.  The other problem I have with playing games online is that real-life interruptions can lead to my death in the game.  If you have kids, you're going to have real-life interruptions.  So I'll go back to playing Oblivion occasionally, and doing other projects (like writing a transportation game, going on scenic drives, and writing web articles).  I do encourage people to try out the free trial (either from FilePlanet or by getting an invitation from someone who already plays), because it's an interesting game for game developers to study.  I'm glad I tried it out.  And I'm glad I didn't become addicted. &lt;code&gt;:-)&lt;/code&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115198482918897571?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115198482918897571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115198482918897571' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115198482918897571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115198482918897571'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/07/world-of-warcraft-first-impressions.html' title='World of Warcraft: First Impressions'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-115000566509100090</id><published>2006-06-10T22:51:00.000-07:00</published><updated>2006-06-11T00:26:11.273-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Playing Oblivion</title><content type='html'>&lt;p&gt;
In case you've been wondering why this blog (and progress on my game) has been quiet lately, it's because I've been playing The Elder Scrolls IV: Oblivion.  It's a fun game, in part because the NPCs do their own thing, and it's fun to watch them.  
&lt;/p&gt;
&lt;p&gt;
Tonight I was running north along one of the main roads, and a bandit jumped out to rob me.  He jumped a bit too late, for I kept running with a bandit on my tail.  I met another bandit, who also started chasing me.  I then met a third bandit and continued to run.  I then saw two of them turn and start chasing a woman on horseback.  She delivers the newspaper daily to all the cities.  She screams and starts to flee downhill.  I turn around and start chasing the bandits, not because I want to save her, but because I want to watch the chase scene.  After chasing her down the hill to the bay, they noticed me and started chasing me instead.  She fled to the south and I went to the north.  I decided to escape by swimming across the bay.  To my amazement, they started swimming too.  I have a magic item that doesn't require me to breathe underwater, so I went underwater and hoped they would drown.  They didn't.  They periodically came up for air.  As I reached the other side of the bay, I looked down and saw the two of them coming up for air, then diving again.  I wasn't able to escape.
&lt;/p&gt;
&lt;p&gt;
I decided to turn east and head for a fort.  Many forts contain monsters, and these monsters often fight humans, including bandits.  Not all of my enemies are friendly towards one another.  At the fort was a troll, a mudcrab, and a bear.  I jumped up to a high perch and watched the two bandits defeat the three creatures.  I then decided to lead them to a nearby cave.  Along the way the bandits killed a wolf, and at the cave they met a minotaur and an ogre.  In Oblivion, ogres are incredibly strong.  It was here that I expected the bandits to meet their end.  Instead, they fled!  They swam across the bay, out of my trap.
&lt;/p&gt;
&lt;p&gt;
I chased the bandits across the bay.  I lost one of them, but saw the other one run up a hill.  I chased him for a while but eventually he got away.  I went back across the bay to the minotaur and ogre, and led them to a nearby goblin cave.  It took three goblins to kill them.  Now I have one goblin remaining.  I took him to another cave, inhabited by a rival tribe of goblins.  Four goblins from the rival tribe killed the one goblin I led there.  I now had four goblins chasing me.  So I took them back to the first goblin tribe's cave.  I kept running back and forth, not actually fighting, but just leading goblins to each others' caves, and the hordes wiped each other out.
&lt;/p&gt;
&lt;p&gt;
Playing this way is amusing.
&lt;/p&gt;
&lt;p&gt;
Having played for 130 hours, I'm about halfway through Oblivion.  It's an interesting game for a game programmer to play.  You can guess what techniques they used for their AI, and then run experiments to see what happens.  I'm probably not playing the way they meant the game to be played.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-115000566509100090?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/115000566509100090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=115000566509100090' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115000566509100090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/115000566509100090'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/06/playing-oblivion.html' title='Playing Oblivion'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114748917616491730</id><published>2006-05-12T19:43:00.000-07:00</published><updated>2006-05-12T20:03:00.750-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Do people really want innovation in games?</title><content type='html'>&lt;p&gt;
People seem to complain that games (and movies) are all the same&amp;mdash;that there isn't enough innovation.  I suspect though that people don't really want innovation.  Guitar Hero is innovative.  Wii is innovative (watch &lt;a href="http://video.google.com/videoplay?docid=-2047904361032006273"&gt;the Wii video from E3&lt;/a&gt;).  But if you enjoyed some game, don't you want more like it?  Or would you rather take your chances with something random?
&lt;/p&gt;
&lt;p&gt;
In the field of machine learning, there is the notion of exploration vs. exploitation.  As you learn things, you want to take advantage of what you've learned.  If you never exploit what you've learned, why bother learning it?  Why bother learning to read if you're never going to read?  However you can't only spend your time doing what you know.  You also want to spend some of your time exploring new things.  Otherwise you may not discover something better than what you know.  100% exploitation is a mediocre strategy.  100% exploration is a bad strategy.  You really want some of each.
&lt;/p&gt;
&lt;p&gt;
In game development, movies, books, etc., it would be a shame if there were no sequels or games similar to existing games.  That would mean that if someone discovers something good, we never do that again.  On the other hand we don't want &lt;em&gt;only&lt;/em&gt; sequels.  I think games like Guitar Hero, Gish, The Sims, Everquest, and Puzzle Pirates demonstrate that there &lt;em&gt;is&lt;/em&gt; innovation out there.  Some people are arguing that there isn't enough.  Others are arguing that there shouldn't ever be sequels.  It's hard to know what the &amp;ldquo;right&amp;rdquo; amount is.  I do believe that the way the free market works, there will be slightly less innovation than is optimal.  It's not zero though.  And I don't believe that you can force the market to innovate more.  Ironically, a market with lots of small independent game companies is likely to produce less innovative games than a market with behemoths like EA.  But that's a story for another day.
&lt;/p&gt;
&lt;p&gt;
I find that of the games I've gotten recently (Black and White 2, The Movies, Guild Wars, Oblivion), I've enjoyed the innovative games &lt;em&gt;less&lt;/em&gt;.  I think that's because the sequels have more refinement in them, and that makes them better than the innovative games, which haven't been tried out on a large scale and don't yet have  the feedback needed for improvement.  I'm trying to spend around 10-20% of my time playing innovative games, in part because I like to study them as a game programmer, but also because I want to spend some of my time exploring new things.
&lt;/p&gt;
&lt;p&gt;
Innovation isn't dead.  It just produces lots of junk, which is what it &lt;em&gt;should&lt;/em&gt; do.  If all innovative games are good, people aren't experimenting enough.  Sequels aren't bad.  If we never had sequels, we'd never be able to polish the rough gems found in the innovative games.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114748917616491730?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114748917616491730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114748917616491730' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114748917616491730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114748917616491730'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/05/do-people-really-want-innovation-in.html' title='Do people really want innovation in games?'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114219908418819794</id><published>2006-03-12T12:29:00.000-08:00</published><updated>2009-01-10T19:19:25.002-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Prediction, Chaos, and Order</title><content type='html'>&lt;p&gt;
When you play a game, can you predict what's going to happen?  I think being able to predict everything makes the game boring.  Being able to predict nothing makes winning unrewarding.  It becomes a game of chance rather than a game of skill.  It's games in between that I'm interested in.
&lt;/p&gt;
&lt;p&gt;
I want skill to be important, so that winning is rewarding, but make each instance of the game different, so that you can play repeatedly.  How can you make the game somewhat unpredictable?
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Multiplayer&lt;/strong&gt;. If you add other humans, and humans are hard to predict, then we can't predict the outcome of the game.  I think however that this isn't sufficient.  If the opponent is good and the game predictable, you can predict what the opponent should do.  Tic-Tac-Toe is an example of a game that's multiplayer but boring.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complexity&lt;/strong&gt;. In some games, the game world is so complex that a human cannot accurately predict what will happen, even if everything were known. Chess is an example of a multiplayer game in which the entire game board is known, but it is not possible for a human to determine the best move.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Randomness&lt;/strong&gt;. If some aspects of the game are random (for example, the roll of the dice), the game will be different each time.  If there's too much randomness, then the winner is essentially random.  If there's too little, then each game will essentially be the same.  But if you get it just right, then the player's skill demonstrates how he reacts to the game.  There's also randomness in physical games.  For example, when playing golf there's some randomness in where the ball goes, just from unpredictable variation in the stroke, and factors like air density and wind.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Information Hiding&lt;/strong&gt;. Some information about the game world can be hidden from the player, and the player's skill can be used to infer aspects of the hidden information.  You can hide the initial game world (for example, the cards initially dealt to each player), the opponent's moves (for example, the cards discarded by an opponent), or the result of randomness (for example, the cards drawn from a shuffled deck during the game).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Many games combine more than one of these.  For example, Chess combines complexity and multiplayer.  Poker combines information hiding, multiplayer, and randomness. Civilization combines all four.
&lt;/p&gt;
&lt;p&gt;
When playing a game that involves randomness, it is important to note that skill is not the only factor; &amp;ldquo;luck&amp;rdquo; matters as well.  In the NCAA tournaments starting this week, as with all sports games, you cannot conclude that the winner is a better player.  You can only conclude that the winner is &lt;em&gt;likely&lt;/em&gt; to be a better player.  That's why rematches are useful&amp;mdash;they let you be more confident in who's better.
&lt;/p&gt;
&lt;p&gt;
My transportation game involves randomness and complexity, and I am undecided about information hiding.  It's a single player game, and I am not planning multiplayer.  After all, I will be the only player.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114219908418819794?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114219908418819794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114219908418819794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114219908418819794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114219908418819794'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/03/prediction-chaos-and-order.html' title='Prediction, Chaos, and Order'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114219214850401539</id><published>2006-03-12T10:58:00.000-08:00</published><updated>2006-03-12T11:35:48.543-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Transportation game, models</title><content type='html'>&lt;p&gt;
I'm trying to use &lt;a href="http://www.systemdynamics.org/DL-IntroSysDyn/stock.htm"&gt;stocks and flows&lt;/a&gt; to create a model for my &lt;a href="http://simblob.blogspot.com/2006/02/rough-sketch-for-transportation-game.html"&gt;transportation game&lt;/a&gt;.  Stocks correspond to nouns and flows correspond to verbs.  At first I thought businesses would be stocks and the transportation of goods would correspond to flows.  But I could also see the businesses as flows (since they consume and produce things) and the cargo areas and trucks as the stocks.  Or maybe both trucks and businesses are flows, and only cargo areas (loading docks) and warehouses are stocks.  Or maybe the cargo itself is the stock.
&lt;/p&gt;
&lt;p&gt;
When it comes to a game, the player's decisions (and the AI's decisions) can directly affect flows, but not stocks.  You can change the rate of production in Warcraft by hiring more peons, researching technology, etc.  Production of gold is a flow.  You do not directly change the amount of gold you have (except by buying something, but I think that's an instantaneous flow).  Gold is a stock.  There's no decision to be made with a stock&amp;mdash;it just exists.  There &lt;em&gt;is&lt;/em&gt; a decision to be made with each flow, because you can throttle it back from its maximum.  There are other decisions to make as well, but the basic resource management decisions (for gold, wood, soldiers, etc.) are about flows, not stocks.
&lt;/p&gt;
&lt;p&gt;
In my game, the player controls the movement of trucks and the AI controls the businesses.  The decisions are based partly on how much of each resource is available.  I'm planning to treat trucks as stocks and the loading/unloading of them as flows.  Businesses will be flows, but their cargo areas will be stocks.
&lt;/p&gt;
&lt;p&gt;
The transfer of cargo is not enough to make an interesting game.  The player will also need to make decisions about infrastructure and placement of transportation systems.  The actual loading and unloading of trucks is boring; it's likely that an AI agent, acting on behalf of the player, will make those decisions.  I still don't have a clear idea of where I'm going with this game, but it's already led me to some interesting topics (operations reseach, system dynamics, supply chain management).
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114219214850401539?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114219214850401539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114219214850401539' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114219214850401539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114219214850401539'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/03/transportation-game-models.html' title='Transportation game, models'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114197178873128350</id><published>2006-03-09T22:15:00.000-08:00</published><updated>2006-03-11T07:21:50.740-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Impolite game: Spellforce 2</title><content type='html'>&lt;p&gt;
I no longer play Guild Wars, Black and White 2, or The Movies, so I've been looking for another game to buy.  Battle for Middle Earth 2 and Spellforce 2 both looked interesting, so I downloaded their demos.
&lt;/p&gt;
&lt;p&gt;
Spellforce 2 won't start the demo unless I install StarForce.  What's the point of copy protecting a demo?  And worse, &lt;a href="http://simblob.blogspot.com/2006/02/polite-games.html"&gt;StarForce is awful&lt;/a&gt; and I am not buying games with it.  So Spellforce 2's demo goes into the recycle bin, and I'm trying out Battle for Middle Earth 2, which looks and sounds nice.  It seems to use SafeDisc, which is perhaps not as bad as StarForce, but still annoying.  It also has lots of splash screens that can't be aborted by pressing &lt;kbd&gt;Esc&lt;/kbd&gt; or &lt;kbd&gt;Enter&lt;/kbd&gt; or &lt;kbd&gt;Space&lt;/kbd&gt; or by clicking the mouse.  Why do games tell you to use NVidia/ATI and Intel/AMD?  Do they really want to tell 75% of their audience that they've chosen badly?  I haven't found a major commercial game as friendly as Guild Wars.  Fortunately Guild Wars is about to release an expansion pack, so perhaps I'll wait for that.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114197178873128350?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114197178873128350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114197178873128350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114197178873128350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114197178873128350'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/03/impolite-game-spellforce-2.html' title='Impolite game: Spellforce 2'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114098526811852501</id><published>2006-02-26T11:46:00.000-08:00</published><updated>2009-01-10T19:19:50.344-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Transportation game, basic objects</title><content type='html'>&lt;p style="float:right;width:454px;margin:1em"&gt;
&lt;a  href="http://simblob.blogspot.com/uploaded_images/interport-746473.png"&gt;&lt;img src="http://simblob.blogspot.com/uploaded_images/interport-743393.png"  alt="picture of example business" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I wanted to start with something simple for my &lt;a href="http://simblob.blogspot.com/2006/02/rough-sketch-for-transportation-game.html"&gt;transportation game&lt;/a&gt;.  I want to explore the transportation of goods between businesses.  I created a simple model:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Business&lt;/strong&gt;. Each business (labeled &lt;strong&gt;B&lt;/strong&gt; in the diagram) can consume and produce items.  For example, a steel mill consumes iron and produces steel.  Some businesses only consume; some only produce.  In my initial implementation, there is only one producer (a dock, where goods are imported from other areas) and one consumer (a retail store, where goods are bought).
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cargo&lt;/strong&gt;. The goods and materials are put into containers (crates, boxes, pallets, etc.) and the containers (labeled &lt;strong&gt;C&lt;/strong&gt; in the diagram) are moved around the game world.  Each container represents some amount of material or goods.  In my initial implementation, there is only one type of cargo (&amp;ldquo;goods&amp;rdquo;) and only one size of container.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loading Areas&lt;/strong&gt;.  A business may not consume goods as soon as they arrive, and it may produce goods that are not immediately picked up.  Loading areas (labeled &lt;strong&gt;A&lt;/strong&gt; in the diagram) are a place for cargo to be stored.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I haven't yet chosen good terminology.  Is it &lt;em&gt;business&lt;/em&gt; or &lt;em&gt;building&lt;/em&gt;? Is it &lt;em&gt;cargo&lt;/em&gt; or &lt;em&gt;container&lt;/em&gt; or &lt;em&gt;goods&lt;/em&gt;?  Consistent use of terminology will help in picking good names in the code.  I want to choose names that are general enough to cover a wide variety of cases.
&lt;/p&gt;
&lt;p&gt;
I think the model has some nice properties.  It's very general, so it can apply to many different kinds of businesses.  For example, a &lt;em&gt;warehouse&lt;/em&gt; is a business that produces the same thing it consumes, and consists almost entirely of loading areas.  The loading areas make it easy for the player to see when the transportation system is working too fast or too slow.  However, there are a lot of unanswered questions at this point.  Does each type of cargo require its own loading area?  Does a business buy from just anyone or does it choose its suppliers?  How are perishable goods represented?  I will leave these questions for later and focus on the simple case: one producer, one supplier, one type of cargo.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114098526811852501?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114098526811852501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114098526811852501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114098526811852501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114098526811852501'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/transportation-game-basic-objects.html' title='Transportation game, basic objects'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114094209904349152</id><published>2006-02-25T23:55:00.000-08:00</published><updated>2009-01-10T19:20:16.533-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Selecting objects in a 3d world</title><content type='html'>&lt;p&gt;
Once I can &lt;a href="http://simblob.blogspot.com/2006/02/navigating-3d-world.html"&gt;move around in my game world&lt;/a&gt;, the next step is to interact with objects.  I need to determine what object, if any, the mouse points at.  There are three general approaches I know of:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;OpenGL picking&lt;/strong&gt;.  In OpenGL, you can use &amp;ldquo;selection mode&amp;rdquo; to identify which object the mouse points at.  This involves assigning a number to each object using &lt;code&gt;glPushName&lt;/code&gt;/&lt;code&gt;glPopName&lt;/code&gt;, then re-rendering the portion of the scene very close to the mouse pointer using &lt;code&gt;gluPickMatrix&lt;/code&gt; and &lt;code&gt;glRenderMode(GL_SELECT)&lt;/code&gt;, then looking at the object numbers that were rendered by reading from the &lt;code&gt;glSelectBuffer&lt;/code&gt; array.  In theory, you can re-render using exactly the same rendering code.  In practice, you want to skip expensive operations like setting up textures, drawing outlines, using shaders, etc.  Once you determine what object was drawn at that location, you still don't know exactly where the mouse points.  I used this approach in SimBlob 2 and was somewhat unhappy with it.  It's easy but it's sort of ugly.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Raycasting&lt;/strong&gt;.  The mouse pointer is a 2d location, and it translates into a &lt;em&gt;ray&lt;/em&gt; in 3d space.  In theory, the ray begins at the camera and goes back into the distance.  In practice, the ray begins at the near plane of the viewing frustum and goes through the far plane.  You can use &lt;code&gt;gluUnProject&lt;/code&gt; to determine where the ray is; use &lt;code&gt;z==0&lt;/code&gt; for the near plane and &lt;code&gt;z==1&lt;/code&gt; for the far plane.  Raycasting works well if you have kept the geometry of all of your objects; it's more of a pain if you generate it on the fly (as I did in SimBlob 2).  You have to implement ray-object intersection for all of your object primitives (triangles, boxes, etc.), and it helps if you have a scene graph or spatial partitioning tree so that you don't have to intersect the ray with &lt;em&gt;every&lt;/em&gt; object in the world.  Once you perform the intersection, the closest hit tells you not only which object is involved but where on that object the mouse points.  This approach requires the most work but it's the most reliable and has the best accuracy.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Depth buffer&lt;/strong&gt;.  Just about everyone is using the depth buffer in a 3d program.  Once you render your scene, OpenGL has the depth (z) value at every pixel.  You can ask for the &lt;code&gt;z&lt;/code&gt; value with &lt;code&gt;glReadPixels&lt;/code&gt;.  You can then compute the world space location of the mouse pointer using &lt;code&gt;gluUnProject&lt;/code&gt; and the &lt;code&gt;z&lt;/code&gt; value you just read.  The final step is to determine what object is at that location.  This approach is easy, but the depth buffer doesn't have much precision, the precision varies among graphics cards, and the depth buffer is altered when using polygon offsets, so it's not reliable.  Another disadvantage is that translucent objects get in the way because they show up in the depth buffer.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I started out using the depth buffer approach, but I've switched to raycasting.  The depth buffer has too little precision to give me the accuracy I wanted.  I also wanted to distinguish between game objects (selectable) and translucent annotations (not selectable), and the depth buffer doesn't give me that level of control.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114094209904349152?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114094209904349152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114094209904349152' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114094209904349152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114094209904349152'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/selecting-objects-in-3d-world.html' title='Selecting objects in a 3d world'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114067091801810465</id><published>2006-02-22T20:51:00.000-08:00</published><updated>2009-01-10T19:20:38.679-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Navigating a 3d world</title><content type='html'>&lt;p&gt;
As I implemented navigation in my 3d world, I had a set of choices to make about how navigation should work.  There's a camera with some &lt;em&gt;position&lt;/em&gt; (x, y, z) pointing in some &lt;em&gt;direction&lt;/em&gt; (&amp;theta;, &amp;rho;) and some type of &lt;em&gt;lens&lt;/em&gt; (field of view).  That gives me 6 variables for the player to control, and that seems like too many.
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Scrolling (Panning)&lt;/strong&gt;. If you scroll &amp;ldquo;up&amp;rdquo;, what direction does the document go?  In most GUI systems, the document goes &lt;em&gt;down&lt;/em&gt;. Try it out in your web browser.  As you drag the scroll bar up, the document moves down.  However, some types of documents move the opposite way.  Try visiting &lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt; and drag the map around.  As you drag the mouse up, the document (map) moves up.  The difference is in what you are dragging.  In most applications (including web browsers), you are dragging the &lt;em&gt;view&lt;/em&gt;.  If you move the view up, you move towards the top of the document, which means the document moves down.  If however you're dragging the &lt;em&gt;document&lt;/em&gt;, it goes in the other direction.  I have been playing Black and White 2 lately, and in it you drag the map.  I initially chose to drag the document (map), but then changed it to dragging the view (camera).
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scroll controls position or velocity&lt;/strong&gt;. If you drag the mouse pointer, does it control the position of the scrolling or the speed?  If you have Firefox or Opera, try the autoscroll feature and compare it to using the scrollbar.  Autoscroll controls the speed; the scrollbar controls the position.    The advantage of controlling the position is that it feels easy to control, especially when combined with dragging the document.  The advantage of controlling the velocity is that you can move around the entire game world without repeatedly lifting the mouse, dragging across the screen, then lifting the mouse again.  Some applications offer both.  Google Earth and some OpenGL demos let you drag to control the position, but if you let go while still dragging, it sets the velocity.  I find this very hard to control.  I chose to make mouse dragging control only the velocity.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotation&lt;/strong&gt;. The camera direction has two degrees of freedom, whether you use angles or vectors, so you need two controls for full control of it.  Some games restrict the camera, and thus may only need one or zero controls.  I chose to fully allow rotation around the z axis and offer minimal control over rotation of the other axis (looking up and down).  Given rotation, there is a choice of rotation point.  Black and White 2 is unusual in that it rotates and zooms around the position you point to with the mouse.  It gives more control but I found it disorienting.  I instead chose to rotate around the center of the screen.  The best rotation point is likely to be something closer to the camera than what I've chosen, but rotating around the center of the screen is easier to implement.
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type of zoom&lt;/strong&gt;.  There are two approaches to zooming.  You can change the &lt;em&gt;lens&lt;/em&gt;.  A &amp;ldquo;telephoto lens&amp;rdquo; has a small field of view and corresponds to &amp;ldquo;zoomed in&amp;rdquo;; a &amp;ldquo;wide-angle lens&amp;rdquo; has a large field of view and corresponds to &amp;ldquo;zoomed out&amp;rdquo;.  (I'm being a bit imprecise; see &lt;a href="http://www.photo.net/learn/fov/"&gt;this article and the comments&lt;/a&gt; if you want the details.)  You can also change the &lt;em&gt;position&lt;/em&gt;.  Moving the camera close to the subject makes it &amp;ldquo;zoomed in&amp;rdquo;; moving it far from the subject makes it &amp;ldquo;zoomed out&amp;rdquo;.  These two approaches are not equivalent.  I chose to keep the lens fixed and move the camera around for zooming.  Dragging the mouse up or down moves the camera up or down, which also rotates the view somewhat.  When the camera is up high, it's rotated to point top-down; when it's near the ground, it's rotated to point forwards.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I started with 6 variables to control.  Dragging the mouse occurs in 2 dimensions, allowing control of 2 variables per button or modifier.  For a typical strategy game, god game, or city builder, the player can move around the entire map, so you probably want to control camera position (2 or 3 variables), camera direction (1 or 2 variables), and zoom (1 variable).  For a first person shooter, the camera must remain at the player's location, so you'd probably want to control camera rotation (2 variables) and zoom (1 variable).  For a third person RPG, you probably want camera rotation (1 variable) and zoom (1 variable).
&lt;/p&gt;
&lt;p&gt;
My game is a simulation, so I want to move the camera in at least 2 dimensions, plus 1 variable for rotation and 1 for zooming.  I don't allow changing the camera lens, so instead zooming involves changing both the camera height and rotation.  That leaves me 4 variables to control with mouse drags.  I'm reserving the left mouse button for interacting with game objects.  I've chosen to assign the right button to scrolling (2 variables); and the middle button to rotation (1 variable) and zooming (1 variable).  These mouse dragging rules make the mouse dragging always control the camera, not the map.  They're simple and self consistent.  They aren't perfect, but I'm happy with them so far.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114067091801810465?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114067091801810465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114067091801810465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114067091801810465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114067091801810465'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/navigating-3d-world.html' title='Navigating a 3d world'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114050681065234600</id><published>2006-02-20T22:18:00.000-08:00</published><updated>2006-02-21T00:46:46.443-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Rough sketch for a transportation game</title><content type='html'>&lt;p&gt;
As I thought about the &lt;a href="http://www-cs-students.stanford.edu/~amitp/simblob/economy.html"&gt;things I learned working on the SimBlob project&lt;/a&gt;, I realized that &lt;a href="http://simblob.blogspot.com/2006/02/change-of-direction.html"&gt;I hadn't explored a lot of the topics I originally wanted to explore&lt;/a&gt;.  I spent my time playing with environmental simulation (water, weather, fires, dams, floods, vegetation, etc.) and never got to anything else.  I decided to start over and focus on a few topics in a simple game.  In my new project I'm going to explore economic simulation and transportation networks.  I have a rough idea of where I'm going, but as I learn things, I expect that the design will change.
&lt;/p&gt;
&lt;p&gt;
There are lots of transportation/economic/city games out there: 
&lt;a href="http://en.wikipedia.org/wiki/Railroad_Tycoon"&gt;Railroad Tycoon&lt;/a&gt;,
&lt;a href="http://tt-forums.net/"&gt;Transport Tycoon&lt;/a&gt;, 
&lt;a href="http://en.wikipedia.org/wiki/SimCity"&gt;SimCity&lt;/a&gt;,
&lt;a href="http://wiki.simutrans.com/tiki-index.php?page=en+"&gt;Simutrans&lt;/a&gt;, 
&lt;a href="http://en.wikipedia.org/wiki/Chris_Sawyer%27s_Locomotion"&gt;Locomotion&lt;/a&gt;, 
&lt;a href="http://www.transportgiant.com/"&gt;Transport Giant&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Traffic_Giant"&gt;Traffic Giant&lt;/a&gt;,
&lt;a href="http://ig2.jowood.com/main.php?lang=en"&gt;Industry Giant&lt;/a&gt;, 
&lt;a href="http://lincity.sourceforge.net/"&gt;LinCity&lt;/a&gt;, 
&lt;a href="http://en.wikipedia.org/wiki/A-Train"&gt;A-Train&lt;/a&gt;,
&lt;a href="http://archive.gamespy.com/reviews/january02/capitalism2/"&gt;Capitalism&lt;/a&gt;,
&lt;a href="http://en.wikipedia.org/wiki/The_Settlers"&gt;The Settlers&lt;/a&gt;, 
&lt;a href="http://www.mobility-online.com/en/informations/generalinformation.html"&gt;Mobility&lt;/a&gt;,

and probably many more.  

There are also many projects in development (some abandoned): 
&lt;a href="http://www.tt-forums.net/viewtopic.php?t=6679"&gt;Transport Empire&lt;/a&gt;, 
&lt;a href="http://www.opencity.info/development.php"&gt;OpenCity&lt;/a&gt;, 
&lt;a href="http://www.tt-forums.net/viewforum.php?f=28"&gt;3DTT&lt;/a&gt;, 
&lt;a href="http://en.wikipedia.org/wiki/Widelands"&gt;Widelands&lt;/a&gt;, 
&lt;a href="http://www.ph2.net/zugspiel/"&gt;Zugspiel&lt;/a&gt;, 

and of course, &lt;a href="http://www-cs-students.stanford.edu/~amitp/games.html"&gt;BlobCity&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
My intent is not to clone one of those games, but instead to explore economic and transportation models by writing a game.  Throughout history, transportation has affected the development of business and vice versa.  The &lt;a href="http://en.wikipedia.org/wiki/Phoenicia"&gt;Phoenicians&lt;/a&gt; used ships to transport goods, and built a trading empire that lasted a thousand years.  The Romans built roads and aqueducts.  The &lt;a href="http://www.netmuslims.com/info/commerce.html"&gt;Arab empire&lt;/a&gt; was based on trade between the east and the west, using caravans and ships.  In the United States, railroads greatly altered the flow of goods and linked the west and east coasts.  The Panama Canal and Suez Canal helped goods flow by ship.  In the late 20th century, advances in transportation made possible the rise of FedEx and the flow of cheap goods from the Asia Pacific region.  The use of &lt;a href="http://en.wikipedia.org/wiki/Containerization"&gt;standard shipping containers&lt;/a&gt; linked ship, rail, and truck transportation systems together.  None of the games I've tried explore all of these ideas.  Have you ever seen a &lt;a href="http://www.scivis.nps.navy.mil/~krgue/Crossdocking/crossdocking.html"&gt;crossdock&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Less-Than-Truckload_%28LTL%29_Shipping"&gt;Less-than-Truckload shipping&lt;/a&gt; in a computer game?  I've been fascinated with these topics and would like to explore them in a simulation game.
&lt;/p&gt;
&lt;p&gt;
The basic idea of the game is that businesses trade with each other using an inefficient transportation network (such as people carrying boxes on foot), and the player can offer better forms of transportation.  As transportation gets cheaper, the businesses make more money, so they expand.  The number of businesses goes down, but the size of the businesses goes up.  Increased volume and a change in business structure means the player has to adapt.  The player has to choose among hand delivery, hand trucks, carriages, gasoline powered trucks, large trucks (semi-trailer trucks), rail, and ships.  As volume goes up, the basic unit being transported gets larger as well, from individual products to boxes to pallets to containers.  Upgrading too early is wasteful; upgrading too late is inefficient.  Reliable transportation infrastructure can affect how businesses and cities develop.  The player has to choose areas of the world to develop, structures to use for each type of good (central distribution, multiple hubs, point to point), sharing among multiple types of goods, temporary storage (warehouses), and modes of transport. As times change, the player has to monitor the efficiency, health, and profitability of the networks and choose which to upgrade, replace, or dismantle.  I'm really not sure whether such a game would be fun for anyone but me.  I tend to like &lt;a href="http://en.wikipedia.org/wiki/Logistics"&gt;logistics&lt;/a&gt; in games.
&lt;/p&gt;
&lt;p&gt;
Given that game programming is just a hobby of mine (and I have plenty of other hobbies), I think the basic idea is too ambitious for me to attempt at first.  Instead I'll design a simpler game and work on that.  I've found in the past that if I take big steps, I'm more likely to fall, so I've learned to take small steps.  I also don't want to spend forever on this game; I have plenty of other topics I want to explore.  Once I've decided my next steps, I'll post them here.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114050681065234600?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114050681065234600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114050681065234600' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114050681065234600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114050681065234600'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/rough-sketch-for-transportation-game.html' title='Rough sketch for a transportation game'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114050238063547929</id><published>2006-02-20T21:05:00.000-08:00</published><updated>2009-01-10T19:20:55.290-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Getting started, 3d world</title><content type='html'>&lt;p&gt;
&lt;a href="http://simblob.blogspot.com/2006/02/getting-started-again.html"&gt;I'm starting a new game project&lt;/a&gt;, not because I think I'll write a cool game, but because I want to explore some ideas (economic simulation and transportation networks).  I decided to use 3d graphics for two reasons:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;strong&gt;I want to learn more 3d programming&lt;/strong&gt;. I've played with GL and OpenGL for a long time but I've never been completely comfortable in a 3d world.  Each time I write an OpenGL program, I learn more about 3d graphics programming.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ease of programming&lt;/strong&gt;. I believe it's &lt;em&gt;easier&lt;/em&gt; to work in a 3d graphics system than in a 2d graphics system, until you get to the point where you want artwork.  Since I don't expect to have nice artwork, I think 3d graphics will be easier. The graphics card handles things like isometric views, filling polygons, gradients, lighting, and textures.  There are simple approaches for mapping screen coordinates to game coordinates and back, because the graphics card does the mapping.  It's very simple to alter the appearance of objects for highlighting and mouse manipulation; you can just change the color or lighting.  And the CPU is freed up for doing things like AI and world simulation.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I started out writing a simple GLUT program that set up a window and the camera, then drew a simple triangle.  Once I got it running, I added stub code for the standard set of GLUT callbacks (mouse handler, keyboard handler, window resize handler).  I changed the scene from a simple triangle to a square grid, added a mouse handler that highlighted the current square, and made the right mouse button drag the camera around.  I then started refactoring the simple GLUT program into modules (mouse, camera, timer, vector algebra, etc.), added simple lighting, improved the camera dragging code, and added some cubes to the scene.  I implemented collision detection between rays and boxes and then used that to highlight the object the mouse pointed to.
&lt;/p&gt;
&lt;p&gt;
Working a little bit each night, I've spent a week on all of this.  It's all graphics code and no real game code.  Have I gotten stuck in a &amp;ldquo;tar pit&amp;rdquo;?  No, although there are some things like lighting and gradients that are dangerous to spend too much time on, I think this initial time setting up the 3d world will be well worth it later on.
&lt;/p&gt;
&lt;p&gt;
When I work with programming languages, I really appreciate having an interactive prompt.  Lisp, Scheme, and Python are much more approachable because they have this.  I can just start Python and inspect variables, create and change objects, explore, test, etc., all without having to go back to my code and insert new commands.  You can also do this with interactive development environments (like Smalltalk's).  I want something similar at the game level, where I can move around freely and click on an object to see all of its properties.  I'd like to create, destroy, and modify objects as the game is running.  I don't expect to build all of this at the very beginning, but having an infrastructure that exposes all the game objects in a uniform way will help me later on.  How much do I really need at this point though?
&lt;/p&gt;
&lt;p&gt;
Two of the approaches used to uniformly represent 3d objects are scene graphs and spatial partitioning (BSP trees, octtrees, bounding box trees, etc.).  Scene graphs are useful for representing changes to lighting, scale, rotation, translation, color, material, textures, and objects with shared components.  For example, instead of representing a complex soldier 3d model for each soldier object, you'd store it once and have it occur multiple times in the scene graph, each time with a different rotation and position.  Spatial partitioning is useful for collision detection.  For example, instead of testing every vehicle against every other vehicle to see if any of them collided, you would partition space into smaller areas and only test vehicles if they are in the same part of the game world.  Both scene graphs and spatial partitioning can also be used to render only the objects that are visible in the scene; this can greatly speed up the rendering.
&lt;/p&gt;
&lt;p&gt;
I've decided that the number of objects in my game is small at the moment and is likely to stay small for some time, so I will use the brute force approach.  I'll test against every object for collision detection, I'll render every object and let the graphics card figure it out, and I'll replicate geometry (vertices, colors, normals, etc.) for each object.  At some point I may need scene graphs and spatial partitioning, and I'll go back and add them in.  Code that depends on whether I have a list or a scene graph should remain as isolated as possible, so that I can switch later.
&lt;/p&gt;
&lt;p&gt;
Having written a minimal 3d world rendering system, I'm ready to go back to designing more of the game.  While exploring new ideas, I tend to alternate between design and implementation.  What I learn from implementation feeds back into the next round of design, and working on the design lets me step back from the implementation to see the big picture.
&lt;/p&gt;
&lt;p&gt;
All &lt;a href="http://www-cs-students.stanford.edu/~amitp/games/interport.tar.gz"&gt; the code for this game&lt;/a&gt; is open source, under the &lt;a href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT license&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114050238063547929?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114050238063547929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114050238063547929' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114050238063547929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114050238063547929'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/getting-started-3d-world.html' title='Getting started, 3d world'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114031356499470679</id><published>2006-02-18T17:17:00.000-08:00</published><updated>2009-01-10T19:21:12.280-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Getting started, again</title><content type='html'>&lt;p&gt;
I'm starting a new game project.  First, I made a list of my goals (which mainly involve &lt;a href="http://simblob.blogspot.com/2006/02/change-of-direction.html"&gt;trying out new things&lt;/a&gt;).  Then I sketched out the idea for a game and thought a little about how it would play and what I would learn by programming it.
&lt;/p&gt;
&lt;p&gt;
Before starting to program though, I started by setting up my programming environment:
&lt;/p&gt;
&lt;ol class=spaced&gt;
&lt;li&gt;&lt;strong&gt;Version control&lt;/strong&gt;.  I set up a &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; repository on local disk.  Later: set up a remote repository, either on a web server or using some code hosting service like Sourceforge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Makefile&lt;/strong&gt;.  I set up a simple Makefile that should work on Linux, Mac OS X, and Windows/Cygwin, using conditional compilation to isolate the platform-specific rules.  Later: figure out automake or makemake or one of those other cross-platform build configuration systems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Notes file&lt;/strong&gt;.  I created a text file where I will keep all my notes.  It needs to be something easy to edit and search through.  Later: use a wiki?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backups&lt;/strong&gt;. I have a script that uses &lt;code&gt;rsync&lt;/code&gt; over &lt;code&gt;ssh&lt;/code&gt; to copy the Subversion repository to another machine. Later: get an off-site backup solution.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Install VMWare&lt;/strong&gt;. VMWare offers their &lt;a href="http://www.vmware.com/products/player/"&gt;Player&lt;/a&gt; for free, and they also offer an &lt;a href="http://www.vmware.com/vmtn/vm/ubuntu.html"&gt;Ubuntu Linux&lt;/a&gt; image for download.  It was &lt;em&gt;very&lt;/em&gt; easy to set this up.  After Ubuntu started up (inside VMWare, running inside Windows XP), I had to install a few more packages (g++, OpenGL+GLUT development libraries, GNU make), but after that I was able to test my code on Linux.  I don't have a similar setup to test on the Mac.  Later: set up a script that will periodically sync with the Subversion repository, attempt to compile, and email any error messages to me.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
After setting up the development environment, I wrote a simple 3D application.  I find it much easier to extend existing code than design everything up front and write it all at once, so I start by writing a very simple program that I can then extend.
&lt;/p&gt;
&lt;p&gt;
My next step on the design side will be to write down a more detailed description of the game world, what the player is supposed to do, and why the task is fun/challenging.  My next step on the implementation side will be to figure out how I want to represent the game world.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114031356499470679?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114031356499470679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114031356499470679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114031356499470679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114031356499470679'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/getting-started-again.html' title='Getting started, again'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-114029763661137829</id><published>2006-02-18T12:43:00.000-08:00</published><updated>2006-02-18T13:26:54.813-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Change of Direction</title><content type='html'>&lt;p&gt;
As I worked on SimBlob 2 and learned more about 3D graphics, I started changing the game from hexagonal to triangular grids.  I then got distracted and started writing &lt;a href="http://www-cs-students.stanford.edu/~amitp/game-programming/grids/"&gt;an article about grids&lt;/a&gt; for my &lt;a href="http://www-cs-students.stanford.edu/~amitp/gameprog.html"&gt;game programming site&lt;/a&gt;.  While writing the article I realized that there are so many other topics I wanted to explore with SimBlob, and never got around to them.  Why?  
&lt;/p&gt;
&lt;p&gt;
I spent most of my time in SimBlob 1 (1994-1998) exploring terrain generation, hexagonal maps, water flow, erosion, multithreaded programming, and GUI libraries.  I spent most of my time in SimBlob 2 (2002-2005) exploring terrain generation, hexagonal maps, &lt;a href="http://simblob.blogspot.com/2005/07/water-simulation.html"&gt;water flow&lt;/a&gt;, erosion, and 3D graphics libraries.  There's a lot of overlap there.  I ended up exploring a lot of the same ideas again.  I love those topics, but they've become &amp;ldquo;&lt;a href="http://www.flipcode.com/articles/article_buildinggame.shtml"&gt;tar pits&lt;/a&gt;&amp;rdquo; for me.  I get stuck, tweaking and trying out new variants, trying to make it just right.  In the end I've learned something and had a lot of fun but haven't gotten much done.  Since I am writing games as a hobby, that's just fine, right?
&lt;/p&gt;
&lt;p&gt;
The trouble is that when I get stuck doing one thing repeatedly, I am not spending my time trying out new things.  I want to use games to explore environmental simulation, business simulation, city simulation, transportation systems, autonomous agents, machine learning and AI, control theory, and emergent behavior.  Of these topics, I've spent most of my time focusing on environmental simulation.  I think that was fine the first time, but after recognizing the tar pits in SimBlob 1, I created them again in SimBlob 2, and ended up getting stuck again on the very same topics.
&lt;/p&gt;
&lt;p&gt;
I've decided to stop working on SimBlob 2 and start working on a new game.  I'm avoiding the tar pits I've had in the past (terrain, water flow, erosion, hexagon/triangle grids) by having a completely flat grid with square tiles and no water.  Sometimes &lt;a href="http://www.marginalrevolution.com/marginalrevolution/2006/01/just_say_yes.html"&gt;doing something quite different is just what you need&lt;/a&gt;.  I want to explore &lt;a href="http://simblob.blogspot.com/2005/08/3d-game-development.html"&gt;3D graphics&lt;/a&gt; some more, but the main focus will be on economic simulation and transportation systems.  I expect to find new tar pits to get stuck in.  &lt;code&gt;:-)&lt;/code&gt;  
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-114029763661137829?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/114029763661137829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=114029763661137829' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114029763661137829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/114029763661137829'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/change-of-direction.html' title='Change of Direction'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-113928111483639396</id><published>2006-02-06T18:34:00.000-08:00</published><updated>2006-03-12T22:28:38.916-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Polite games</title><content type='html'>&lt;p&gt;
A few months ago I mentioned that &lt;a href="http://simblob.blogspot.com/2005/06/guild-wars-friendliness.html"&gt;Guild Wars is polite&lt;/a&gt;, and as a result, I play a lot more.  I still play Guild Wars occasionally.  It's so easy to start up, and I don't have to go find the CD.
&lt;/p&gt;
&lt;p&gt;
The two games I've gotten since then are &lt;em&gt;The Movies&lt;/em&gt; and &lt;em&gt;Black and White 2&lt;/em&gt; (both from Lionhead Studios).  Both of them have long startup sequences.  They show me splash screens and advertisements (for Intel and ATI) every time.  Then only after the splash screens are shown does the game start loading.  At the very least the game should load while the splash screens are up!  In addition, the CD has to be in the drive for the game to start.  That means it's a major pain to go back and forth between the games.
&lt;/p&gt;
&lt;p&gt;
I find that I'm playing the polite game more than the impolite games.  If I'm in the mood to play a game but I have to go find the CD, I'm less likely to play that game.  And every time I have to sit there looking at the Lionhead Studios logo, I'm reminded of the company that makes me sit there instead of taking me straight to the game.
&lt;/p&gt;
&lt;p&gt;
Another impolite practice used by many game companies is to use nasty copy protection techniques.  I don't get games from the file sharing networks, but it makes me unhappy that pirates are getting a &lt;em&gt;better game experience&lt;/em&gt; than I am!  (Copy protection gives people more incentive to get a pirate copy instead of buying the game.)  What I find totally weird is that StarForce copy protection is even used for &lt;em&gt;game demos&lt;/em&gt;.  What's the point of making a &lt;em&gt;free&lt;/em&gt; demo uncopyable??  StarForce remains on my system even though I've uninstalled the King Kong demo.  That's awful.  I'm &lt;em&gt;not&lt;/em&gt; going to buy any of those games now.
&lt;/p&gt;
&lt;p&gt;
You can find instructions for removing StarForce on &lt;a href="http://www.glop.org/starforce/"&gt;this StarForce Boycott site&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Make your software polite, and I'll use it more.  Make your software rude, and I'll avoid it.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; [2006-03-12] After removing the StarForce drivers, I discovered that my CD-ROM drive was in "PIO" mode instead of "DMA" mode like it should be.  This is a symptom of StarForce having been on my system.  I uninstalled the IDE drivers in Windows XP and rebooted, and it reinstalled them in DMA mode.  PIO mode on some newer drives causes damage over time; I don't know if my drive has suffered any damage.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-113928111483639396?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/113928111483639396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=113928111483639396' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113928111483639396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113928111483639396'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/02/polite-games.html' title='Polite games'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-113794960251710113</id><published>2006-01-22T08:47:00.000-08:00</published><updated>2006-01-22T09:06:42.556-08:00</updated><title type='text'>SRE on the web</title><content type='html'>&lt;p&gt;
Ten years ago, I lost the source code to Solar Realms Elite (SRE), a game I had worked on.  Since then, many people have &lt;a href="http://www-cs-students.stanford.edu/~amitp/Articles/SRE-Clones.html"&gt;wanted to build a clone&lt;/a&gt;.  I've tried to help them, both through email and by posting &lt;a href="http://www-cs-students.stanford.edu/~amitp/Articles/SRE-Design.html"&gt;what I remember about the game's design&lt;/a&gt;.  However, most of the projects had not gotten very far.
&lt;/p&gt;
&lt;p&gt;
Yanick Bourbeau has built a web version of SRE called &lt;a href="http://sre.servegame.com/"&gt;Imperium Galactica&lt;/a&gt; (which also happens to be the name of &lt;a href="http://www.avault.com/reviews/review_temp.asp?game=imperium"&gt;an older, unrelated game&lt;/a&gt;).  It's fairly complete and offers a few things SRE did not (like simultaneous play by several players).  I've been playing for a few days and it's fun!  The game isn't quite balanced yet, but that will take a little bit of time to fine tune.  Try it out!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-113794960251710113?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/113794960251710113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=113794960251710113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113794960251710113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113794960251710113'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2006/01/sre-on-web.html' title='SRE on the web'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-113595883063306386</id><published>2005-12-30T07:57:00.000-08:00</published><updated>2005-12-30T08:37:57.446-08:00</updated><title type='text'>SVG woes</title><content type='html'>&lt;p&gt;
I've been working on some new illustrations for my game programming pages.  In the past I had created bitmap diagrams using Gimp or by writing custom code.  This time I'm using Inkscape, which produces SVG, in the hopes that I can directly embed SVG onto the web page.
&lt;/p&gt;
&lt;p&gt;
Unfortunately browser support for SVG stinks.
&lt;/p&gt;
&lt;p&gt;
First, not all browsers support SVG.  So you need a fallback.  That's fine; I can produce PNGs with Inkscape.
&lt;/p&gt;
&lt;p&gt;
Second, there's the question of whether to use &lt;a href="http://www.svgfaq.com/Starting.asp"&gt;&lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; tags&lt;/a&gt;.  The answer seems to be that &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; is the &amp;ldquo;right&amp;rdquo; answer, but it &lt;strong&gt;crashes Safari 1.0&lt;/strong&gt;.  So I should use &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt;, right?  I would, except &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; &lt;strong&gt;doesn't support fallbacks&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
This means that I to support browsers without SVG (by using PNG fallbacks), I have to crash the Safari browser.  Ugh.
&lt;/p&gt;
&lt;p&gt;
Even if that problem is solved, the next problem is that different SVG implementations support different features.  Adobe's SVG plugin, Mozilla/Firefox SVG, and Opera SVG are all different.  Even the very simple SVG I wrote does not work the same on all three.  Opera does not seem to support text at all.
&lt;/p&gt;
&lt;p&gt;
Browser vendors: &lt;strong&gt;it's worse to have limited SVG support than no support&lt;/strong&gt;.  With no support, the fallback will be used, and the reader will see something useful.  With limited support, the reader will get a broken diagram.
&lt;p&gt;
&lt;p&gt;
Even if browsers supported SVG, the web server I use does not use the correct MIME type.  It sends &lt;code&gt;text/xml&lt;/code&gt; instead of &lt;code&gt;image/svg+xml&lt;/code&gt;.  I'm not sure how much this matters in practice though.  (Side note: I find it interesting the change from &lt;code&gt;text&lt;/code&gt; to &lt;code&gt;image&lt;/code&gt;.  This is going to generally be a confusing point with XML, since it's text underneath, but the rendering of it may not be.)
&lt;/p&gt;
&lt;p&gt;
I have decided not to embed SVG on my pages (although I might link to it).  I will turn SVG into PNG and embed PNG on my pages.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-113595883063306386?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/113595883063306386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=113595883063306386' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113595883063306386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113595883063306386'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/12/svg-woes.html' title='SVG woes'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-113444740568029295</id><published>2005-12-12T19:55:00.000-08:00</published><updated>2005-12-12T20:16:45.703-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Black and White 2 AI</title><content type='html'>&lt;p&gt;
I played &lt;a href="http://en.wikipedia.org/wiki/Black_%26_White_2"&gt;Black and White 2&lt;/a&gt; for many hours yesterday.  The computer player and I were in a stalemate.  The computer kept sending armies against me and I kept defeating them.  I had built my town with walls around it, and then put archers on top of the walls.  I was building up my strength while defending myself, in preparation for a big attack.  I felt pretty safe.
&lt;/p&gt;
&lt;p&gt;
After around 40 attacks, I realized that they weren't all the same.  The computer wasn't using the same attackers each time.  It tried the creature, archers, swordsmen, and catapults.  It tried combinations of them.  Sometimes it would come through my main entrance, and sometimes it would come around the back entrance to the city.  The computer player also destroyed major sections of the city using the &amp;ldquo;earthquake&amp;rdquo; power, but I recovered from these too.  After a while the enemy creature figured out that he should kick my wall in.  His archers and swordsmen stayed back, out of range, while the creature came up and destroyed my wall, including the archers on it.  After it breached the wall, the army swarmed into my town and killed half my people.
&lt;/p&gt;
&lt;p&gt;
I rebuilt my wall and started to recover, but the computer's newly discovered strategy worked well.  It tried several variants but kept going back to the same approach: kick down the wall, then swarm the town.  This forced me to try some new strategies.  Although being on the wall has advantages, it leaves the archers vulnerable when the enemy creature attacks the wall.  So I moved them behind the wall.  I've also learned to open my gate, wait for the enemy army to get close, then close the gate and set their army on fire.  I have no good strategy for the creature knocking down my wall though, and I'm constantly losing townspeople and then rebuilding.
&lt;/p&gt;
&lt;p&gt;
After a long stalemate, the computer AI learned how to attack more effectively, and now I'm having trouble keeping my city safe.  I'm very impressed by the AI.  I'm not sure how it's programmed, but it tried out many different things and learned which ones work the best.  From the game AI techniques I've learned (genetic algorithms, neural networks, fuzzy logic, state machines, etc.), the AI in Black and White 2 seems to match most closely with what I know about &lt;a href="http://en.wikipedia.org/wiki/Reinforcement_learning"&gt;reinforcement learning&lt;/a&gt;.  It's a technique that uses online learning (observing results as the game is played) instead of training (from examples constructed ahead of time), allows both exploration (trying new things in order to learn) and exploitation (taking advantage of what you've learned), and associates rewards (like whether the attack was successful) with actions (like kicking down the wall and keeping the army away from my archers).  I recommend &lt;a href="http://www.cs.ualberta.ca/~sutton/book/the-book.html"&gt;Sutton and Barto's book&lt;/a&gt; if you want to learn more.  It's entirely possible though that the game uses something much simpler that just happens to look impressive, but my guess is that it's using reinforcement learning.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-113444740568029295?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/113444740568029295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=113444740568029295' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113444740568029295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/113444740568029295'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/12/black-and-white-2-ai.html' title='Black and White 2 AI'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-112455425334545809</id><published>2005-08-20T08:56:00.000-07:00</published><updated>2009-01-10T19:21:57.381-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>3D Game development</title><content type='html'>&lt;p&gt;
My &lt;a href="http://www-cs-students.stanford.edu/~amitp/gameprog.html"&gt;game programming&lt;/a&gt; page contains information about platform-independent game programming topics, but when I actually write a game I need to combine that with platform-specific code.  These days I use either &lt;a href="http://pygame.org/"&gt;PyGame&lt;/a&gt;, Java2D, or OpenGL.  My favorite OpenGL resources over the last six months have been:
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;&lt;a href="http://www.codesampler.com/"&gt;CodeSampler&lt;/a&gt;, which contains lots of examples of OpenGL code to do various things like textures, shaders, transparency, and lighting.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nehe.gamedev.net/"&gt;NeHe's Tutorials&lt;/a&gt;, which covers similar topics.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.gamedev.net/reference/list.asp?categoryid=31"&gt;Gamedev.net OpenGL Articles&lt;/a&gt;, which includes a few random topics.  Unfortunately most of the Graphics articles on GameDev are old and obsolete; they teach you how to implement algorithms that are already implemented in hardware these days.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.flipcode.com/articles/index.shtml"&gt;FlipCode's Featured Articles&lt;/a&gt; cover many graphics-related topics but do not focus too much on OpenGL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In addition, I've been reading Dave Eberley's &lt;em&gt;Game Physics&lt;/em&gt; and Van Verth's &lt;em&gt;Essential Mathematics for Games &amp;amp; Interactive Applications&lt;/em&gt;.  These books are not primarily about graphics; they are about representing objects in 3D, manipulating them, etc. I also took a look at Stahler's &lt;em&gt;Beginning Math and Physics for Game Programmers&lt;/em&gt; but didn't like it as much.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-112455425334545809?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/112455425334545809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=112455425334545809' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112455425334545809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112455425334545809'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/08/3d-game-development.html' title='3D Game development'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-112101090238128627</id><published>2005-07-10T08:50:00.000-07:00</published><updated>2006-03-04T21:02:03.743-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Water simulation</title><content type='html'>&lt;p&gt;
&lt;img src="http://theory.stanford.edu/~amitp/simblob/blob-game-variable-width-river.png" /&gt;
&lt;/p&gt;
&lt;p&gt;
One of the most fun things about SimBlob is the water simulation.  It isn't great though, and I keep looking for ways to make it better.
Using the &lt;a href="http://en.wikipedia.org/wiki/Navier-Stokes_equations"&gt;Navier-Stokes equations&lt;/a&gt; is the &amp;ldquo;right&amp;rdquo; way to simulate fluids, but they're complicated and expensive, so many people have come up with approximations or alternatives.  Here are some resources:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.ventrella.com/Ideas/Fluid/fluid.html"&gt;Fluid Dynamics Model&lt;/a&gt; (includes demo for Windows)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.unc.edu/~blloyd/comp259/project/"&gt;Fluid Dynamics with Erosion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.double.co.nz/dust/GDC03.pdf"&gt;Real-Time Fluid Dynamics for Games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.darwin3d.com/gamedev/articles/col0100.pdf"&gt;Reflections on Water Simulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://graphics.stanford.edu/~fedkiw/papers/stanford2001-02.pdf"&gt;Practical Animation of Liquids&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
None of their solutions directly works for me, since I'm using a hexagonal grid and have a dynamic landscape underneath the water.
&lt;/p&gt;
&lt;p&gt;
[2005-07-11] &lt;strong&gt;Update:&lt;/strong&gt; I tried some approaches based on the above, but they didn't work for me.  It's quite possible that I'm missing an essential step in my simplification.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-112101090238128627?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/112101090238128627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=112101090238128627' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112101090238128627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112101090238128627'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/07/water-simulation.html' title='Water simulation'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-112100996539907949</id><published>2005-07-10T08:35:00.000-07:00</published><updated>2006-02-20T22:17:07.506-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>SimBlob 2, now for Mac</title><content type='html'>&lt;p&gt;
I've added a Mac makefile to the &lt;a href="http://www-cs-students.stanford.edu/~amitp/games/simblob2.tar.gz"&gt;download&lt;/a&gt;, but I haven't tested it myself.  The main changes involved file paths.  On Linux and Windows, OpenGL is &lt;code&gt;#include &amp;lt;GL/gl.h&amp;gt;&lt;/code&gt;; on the Mac, it's &lt;code&gt;#include &amp;lt;OpenGL/gl.h&amp;gt;&lt;/code&gt;.  On Linux and Windows, GLUT is &lt;code&gt;#include &amp;lt;GL/glut.h&amp;gt;&lt;/code&gt;; on Mac it's &lt;code&gt;#include &amp;lt;GLUT/glut.h&amp;gt;&lt;/code&gt;.  I admit that the Mac directory names make more sense, but it's annoying given that the include has been &lt;code&gt;GL/gl.h&lt;/code&gt; for a decade on other systems.  The other change involved the linker options; you have to specify a &lt;code&gt;-framework&lt;/code&gt;.  Thanks to my friend Richard T for figuring all of this out.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-112100996539907949?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/112100996539907949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=112100996539907949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112100996539907949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112100996539907949'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/07/simblob-2-now-for-mac.html' title='SimBlob 2, now for Mac'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-112044879261803843</id><published>2005-07-03T20:29:00.000-07:00</published><updated>2005-07-03T21:16:46.740-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>SimBlob 2, now for Windows</title><content type='html'>&lt;p&gt;
When I started working on &lt;a href="http://www-cs-students.stanford.edu/~amitp/simblob/economy.html"&gt;Simblob 2&lt;/a&gt; back in 2002, &lt;a href="http://simblob.blogspot.com/2003/02/simblob-2.html"&gt;I decided to use OpenGL and GLUT&lt;/a&gt;.  Even though I was developing in Linux, I didn't want to end up in the situation I had with Simblob 1, which only works in OS/2.  I finally took advantage of the portable libraries for SimBlob 2 and got it running on my &lt;a href="http://flickr.com/photos/amitp/4284134/"&gt;new computer&lt;/a&gt;, which runs Windows XP.
&lt;/p&gt;
&lt;p&gt;
I use Cygwin in Windows, so the Unix level libraries are fairly similar.  The main difference was that the paths are different.  In Linux, I used &lt;code&gt;-lglut -lGLU -lGL&lt;/code&gt;, and the compiler was able to find all the headers and libraries.  To make it run in Windows/Cygwin, I changed it to &lt;code&gt;-I/usr/include/w32api -L/lib/w32api -lglut32 -lglu32 -lopengl32&lt;/code&gt;.  Also, &lt;code&gt;glext.h&lt;/code&gt; wasn't automatically included, so I had to insert &lt;code&gt;#include &amp;lt;GL/glext.h&amp;gt;&lt;/code&gt;.  In addition, the multitexturing functions (&lt;code&gt;glActiveTextureARB&lt;/code&gt;, &lt;code&gt;glClientActiveTextureARB&lt;/code&gt;, and &lt;code&gt;glMultiTexCoord2fARB&lt;/code&gt;) don't seem to exist on my system, so I worked around that by using a single texture instead.  I'll figure that one out later.  I might need to use &lt;code&gt;wglGetProcAddress&lt;/code&gt; to get those functions (unfortunately that function is Windows specific).
&lt;/p&gt;
&lt;p&gt;
The one remaining problem I'm having is that when I quit the program by closing the window, GLUT's main loop doesn't exit.  It instead starts eating up 100% of the CPU and never terminates.  I'm not yet sure if this is a GLUT issue or a Cygwin issue.  My workaround is to use Ctrl-C to exit instead of closing the window.
&lt;/p&gt;
&lt;p&gt;
At the moment Simblob depends on Cygwin.  You can't just run the Simblob executable; you have to have Cygwin installed.  I'd like to try using the MingW option (&lt;code&gt;gcc -mno-cygwin&lt;/code&gt;); I just need to remove some other dependencies on Unix libraries first.
&lt;/p&gt;
&lt;p&gt;
I should probably spend some time learning &lt;code&gt;autoconf&lt;/code&gt; or some other tools that help manage builds on multiple platforms.
&lt;/p&gt;
&lt;p&gt;
I don't have a Mac handy, but it shouldn't be too hard to make Simblob 2 work on a Mac.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-112044879261803843?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/112044879261803843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=112044879261803843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112044879261803843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112044879261803843'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/07/simblob-2-now-for-windows.html' title='SimBlob 2, now for Windows'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-112031932396930126</id><published>2005-07-02T08:32:00.000-07:00</published><updated>2005-12-16T08:52:03.716-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Games in Javascript</title><content type='html'>&lt;p&gt;
A few weeks ago Google Maps got me thinking about writing simple games in Javascript.  In particular, how much of &lt;a href="http://www-cs-students.stanford.edu/~amitp/simblob/economy.html"&gt;The Silver Kingdoms&lt;/a&gt; could I implement in a browser?  If I drop the terrain and make it a 2D overhead game (or possibly isometric, but that might be harder to implement), what I would need from the browser is (a) AJAX support (so the simulation can run on a server and send updates to the browser) and (b) transparent overlays for sprites.  There are some nice advantages of writing in a browser.  The basic graphics code is already there (image display, animation, positioning, layering) and the basic UI code is already there (mapping clicks to objects, overlapping windows, form controls).  The real question is whether it's feasible&amp;mdash;can the browser smoothly animate lots of sprites on the screen at once?
&lt;/p&gt;
&lt;p&gt;
A few days later I read that someone had created a &lt;a href="http://www.vestaldesign.com/vestalblog/2005/06/star-wars-attacks-google-maps.html"&gt;Star Wars&lt;/a&gt; hack on top of Google Maps.  And then I saw someone had created an &lt;a href="http://moloko.itc.it/paoloblog/archives/2005/07/01/animated_invasion_over_google_map.html"&gt;animated Microsoft campus invasion hack&lt;/a&gt;.  There's now a &lt;a href="http://moloko.itc.it/trustmetricswiki/moin.cgi/GamesOnGoogleMaps"&gt;wiki page&lt;/a&gt; with a list of Google Map hack game ideas.
&lt;/p&gt;
&lt;p&gt;
There are only 9 sprites on the animated invasion hack, but it feels rather choppy.  I'm not sure if this is a browser issue, an issue with the demo, or an issue with the Google Maps API.  If it's a browser issue then it's unlikely that any nice games are going to be written on top of Google Maps.  If it's a Maps issue, then a game using its own map might be feasible.
&lt;/p&gt;
&lt;p&gt;
Some links I've collected while looking for ways to implement a simple game (SimCity-ish) in Javascript:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Examples for &lt;a href="http://www.youngpup.net/2001/domdrag/examples"&gt;drag and drop of objects&lt;/a&gt; in Javascript&lt;/li&gt;
&lt;li&gt;A &lt;a href="http://mike.teczno.com/giant/pan/"&gt;drag and drop map&lt;/a&gt;, like Google Maps, but with your own maps&lt;/li&gt;
&lt;li&gt;A description of the &lt;a href="http://developer-test.mozilla.org/en/docs/Drawing_Graphics_with_Canvas"&gt;canvas element&lt;/a&gt; in Firefox 1.1 and Safari, which could be used for drawing graphics in the browser&lt;/li&gt;
&lt;li&gt;A &lt;a href="http://script.aculo.us/"&gt;library for special effects&lt;/a&gt; in Javascript (including drag and drop)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I hadn't been considering using Google Maps itself, because a SimCityish game where you can't actually modify the city would be boring.  I think it might be feasible to build a war or transportation game on top of Google Maps, but the game would need some notion of what the objects on the map are, and that might take some image recognition heuristics.  It's unlikely I'll actually implement a real game this way, but I might try a little demo game.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update [2005-12-16]:&lt;/strong&gt; Take a look at &lt;a href="http://llor.nu/"&gt;this game&lt;/a&gt;.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-112031932396930126?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/112031932396930126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=112031932396930126' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112031932396930126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/112031932396930126'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/07/games-in-javascript.html' title='Games in Javascript'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-111919515355092698</id><published>2005-06-19T08:29:00.000-07:00</published><updated>2009-01-10T19:22:20.366-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Guild Wars Friendliness</title><content type='html'>&lt;p&gt;
There's something about Guild Wars that I don't see mentioned much: it has a very friendly interface that encourages casual play.
&lt;/p&gt;

&lt;ul class=spaced&gt;
&lt;li&gt;The CD doesn't have to be in the drive.  When I'm thinking of playing, I don't need to take the previous CD out of the drive, put the Guild Wars CD in, and &lt;em&gt;then&lt;/em&gt; start the game.  I can just start the game right away.  Since it's no hassle, I play a lot more.&lt;/li&gt;
&lt;li&gt;When I start the game, it goes right to the login prompt.  No publisher splash screen.  No developer splash screen.  No video card maker splash screen.  No sound library splash screen.  No introductory movie.  No copyright screen.  No disclaimer screen.  No menu.  No loading progress bar.  &lt;em&gt;It's really quick and easy to get into the game.  This encourages me to play more.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;While you're playing the game there are Minimize, Maximize, Close buttons at the top right corner.  This lets you easily switch to another application or run the game in windowed mode or just stop playing.  It acts much more like a standard application, and it's very smooth.  I feel like I can play at any time, and then switch back to whatever I was doing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
All of these seem very minor but I think they add up to something big: I'm playing Guild Wars a &lt;em&gt;lot&lt;/em&gt; (over 200 hours).  I wish all games would be this way.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-111919515355092698?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/111919515355092698/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=111919515355092698' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/111919515355092698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/111919515355092698'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/06/guild-wars-friendliness.html' title='Guild Wars Friendliness'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-111522457372505366</id><published>2005-05-04T08:59:00.000-07:00</published><updated>2005-05-04T09:36:13.763-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>Guild Wars</title><content type='html'>&lt;p&gt;
After playing Neverwinter Nights for a few months, I got tired of it.  I played the main campaigns and enjoyed them.  The problem is that the mods are much harder to deal with than they should be.  It takes a lot of effort to find mods that you can play (level restrictions, number of players, good ratings, etc.).  It then takes more effort than it should to download and install them.  They come in ZIP, EXE, and RAR formats.  They come with multiple files, each of which may have to be put into a different folder.  Bioware could have made mods easier by keeping all the mod files in a single folder and by standardizing on the distribution format.  For example, if the game could read ZIP files, you could just download the file and put it in a particular folder and it would be ready, without unpacking it.  In any case, the main problem I had was that it was hard for me to find and try out mods, so I didn't try many, and I didn't find many that I liked.
&lt;/p&gt;
&lt;p&gt;
I've been playing &lt;a href="http://guildwars.com/"&gt;Guild Wars&lt;/a&gt; this week (22 hours so far).  This is an action RPG, much like Diablo, but it also has more quests.  One thing that struck me was that Diablo 2 wasn't considered an MMORPG, but Guild Wars sometimes is, and the two games aren't substantially different in that respect.
&lt;/p&gt;
&lt;p&gt;
Diablo 2 lets you play offline (one player) or online (one or multiple players).  Guild Wars lets you play online only.  This seems like a good idea.  If you know that everyone's online, you can have a much quicker update cycle (those of you who waited over a year for the 1.09 Diablo 2 patch know why this matters).  So far I've had &lt;a href="http://guildwars.com/news/gameupdates.html"&gt;3 small updates&lt;/a&gt; in 4 days.  Requiring online play also means you can learn how people play and make game balance adjustments frequently.
&lt;/p&gt;
&lt;p&gt;
Diablo 2, in online mode, puts you in one of many chat rooms.  The main purposes of this room are to chat, to find people to play with, and to trade.  There are several chat rooms (presumably to avoid overcrowding), including some specifically for trading.  When joining a game, you see a list of games that are at your level (Normal/Nightmare/Hell).  People generally want to find a game that's not only at their level but in the same general areas.  They sometimes do this by announcing their area (&amp;ldquo;Act III - Staff quest&amp;rdquo;) in the game name, but there's no easy way to filter or sort the games to find the areas you care about.  Once you join a game, you don't see everyone anymore; you only see your party.  Every time you join a game, the world resets&amp;mdash;all the monsters are back, and the layout is randomized.  When you leave a game, you abandon your party.
&lt;/p&gt;
&lt;p&gt;
Guild Wars feels like an MMORPG because it puts you into the game right away.  You're in a city, with lots of other people around, and you can see everyone walking around, talking, getting quests, etc.  But these cities are essentially chat rooms.  Their main purpose is for people to chat, find people to play with, and trade.  Once you join a party and go out to play the game, you don't see everyone anymore; you only see your party.  Every time you go out, the world resets&amp;mdash;all the monsters are back (but the layout is not randomzied as it was in Diablo).  When teleport into a city, you abandon your party.
&lt;/p&gt;
&lt;p&gt;
There are of course other differences.  In Diablo, you can only get quests once you go into the game.  In Guild Wars, you can get quests in the chat area (cities).  Since a party may want to go into a city to get quests, the party is not broken up if you walk into a city; it's only broken up if you teleport.  In Diablo, if you want to trade with someone, you find them in the chat room and then you have to create a game to trade with them.  In Guild Wars, if you want to trade with someone, you can trade with them in the city where you met them; there's no need to go anywhere.  Also, Guild Wars has a special trading chat channel.  You can tune in to both the regular and the trading channel; you don't have to go somewhere to find the traders.  Guild Wars also makes it easier to find a party or to play PvP.
&lt;/p&gt;
&lt;p&gt;
Why does Guild Wars keep the Diablo-style chat vs. game area distinction?  I think it's for efficiency.  Chat areas handle hundreds of people; game areas handle up to four.  Chat areas are easier to make efficient because you don't need strict ordering of events.  If you say something and I say something at roughly the same time, it doesn't matter so much which is heard first.  And it doesn't matter so much if it takes 250 ms to show up.  If you attack someone and I attack someone at the same time, it matters a great deal which one occurred first, and it needs to be decided and sent to all clients much quicker than 250 ms.  By segregating the chat (lots of clients, loose ordering of events, high latency) and the game (few clients, strict ordering of events, low latency), you can make both efficient.  If you tried to combine the two, you open up a new hard problem: what happens when you have lots of clients and you need low latency?  Trying to tackle that rare but important case makes your life as a game developer more difficult.  You're spending less time on other things that may have mattered more to the players.
&lt;/p&gt;
&lt;p&gt;
Another thing that Guild Wars doesn't handle is massive persistence.  You can only drop items in the game areas, not the chat areas.  So if you drop an item, it only has to be seen by a few other clients, and it goes away as soon as you enter a city.  That way you don't need to coordinate item locations among tens of thousands of clients.  You can assign each city area and each game area to a separate server.  Since city and game servers keep no state, you can add more servers transparently.  You don't have to require players to choose a server ahead of time and then find that they can't play with their friends, who happen to live on a different server.
&lt;/p&gt;
&lt;p&gt;
So far I've been really impressed with what I can infer of the design of Guild Wars.  It's fast, has great graphics, and lots of fun.  It's an incredibly addictive game.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-111522457372505366?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/111522457372505366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=111522457372505366' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/111522457372505366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/111522457372505366'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2005/05/guild-wars.html' title='Guild Wars'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-110218003348898032</id><published>2004-12-04T08:52:00.000-08:00</published><updated>2004-12-04T09:07:50.460-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Product placement and games</title><content type='html'>&lt;p&gt;
&lt;a href="http://knowledge.wharton.upenn.edu/index.cfm?fa=viewArticle&amp;amp;id=1093"&gt;Product Placement&lt;/a&gt; is a way to get your product seen without using traditional advertising.  I think product placement could be used for market research too.  Imagine an online game that doesn&amp;rsquo;t offer &lt;em&gt;only&lt;/em&gt; Coca-Cola (product placement), but offers &lt;em&gt;lots&lt;/em&gt; of drinks.  You could then correlate the choice of drinks with demographic information you have about your gamers&amp;mdash;age, gender, income, and so on.  By watching activities within the game, you could correlate the choice of drinks with MUD personality types (&lt;a href="http://www.brandeis.edu/pubs/jove/HTML/v1/bartle.html"&gt;Killers, Achievers, Socializers, Explorers&lt;/a&gt;); this might tell you what kinds of magazines you want to advertise in.  You could see whether people who hang out together are more likely to drink the same sorts of drinks (energy boosters, soda, water, juices, etc.).  You could pay some people to switch drinks and see whether others follow.  You can measure correlations between products (do people who drink Red Bull also eat hamburgers?).
&lt;/p&gt;
&lt;p&gt;
Does this creep you out?  It should (unless you work in marketing).  Product placement is what we have now, but I think in the future we&amp;rsquo;ll have people using virtual worlds as a way to run experiments on us.  In virtual worlds you can measure behavior better.  There is of course the question of whether product choice and behavior in the virtual world differs from the physical world, but having detailed data about a million players can complement having sparse data about a few thousand survey participants.  Given that games&amp;mdash;unlike movies&amp;mdash;let players choose what to do, product placement in games seems like a waste.  Market research seems to me to be a much more valuable way to use that opportunity.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-110218003348898032?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/110218003348898032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=110218003348898032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/110218003348898032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/110218003348898032'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2004/12/product-placement-and-games.html' title='Product placement and games'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-110037189899755126</id><published>2004-11-13T10:51:00.000-08:00</published><updated>2004-11-13T10:51:38.996-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Playing characters in games</title><content type='html'>&lt;blockquote&gt;
It’s actually very interesting in The Sims how the pronouns change all the time. I’m sitting there playing the game and I’m talking about, "Oh, first I’m going to get a job, then I’m going to do this, then I’m going to do that." And then you know when the character starts disobeying me, all of a sudden I shift and say "Oh, Why won’t he do that?" or "What’s he doing now?" And so at some point it’s &lt;em&gt;me&lt;/em&gt; kind of inhabiting this little person, and I’m thinking, "It’s me, I’m going to get a job and I’m going to do x, y, and z." But then when he starts rebelling, it’s &lt;em&gt;he&lt;/em&gt;. And so then I kind of jump out of him, and now it’s me vs. &lt;em&gt;him&lt;/em&gt;. You know what I’m saying?
&lt;/blockquote&gt;
&lt;p&gt;
&amp;mdash; from Celia Pearce&amp;rsquo;s &lt;a href="http://gamestudies.org/0102/pearce/"&gt;interview with Will Wright&lt;/a&gt;
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-110037189899755126?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/110037189899755126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=110037189899755126' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/110037189899755126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/110037189899755126'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2004/11/playing-characters-in-games.html' title='Playing characters in games'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-109928753795120263</id><published>2004-10-31T21:29:00.000-08:00</published><updated>2010-09-04T08:38:33.440-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Road building applet</title><content type='html'>&lt;p&gt;
A few months ago I had been thinking about a UI for building roads and rails.  When I got Locomotion, I found that &lt;a href="http://simblob.blogspot.com/2004/10/god-games-locomotion.html"&gt;the building UI was a little bit annoying&lt;/a&gt;, and that inspired me to work on my UI some more.  I tried Flash but &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-flash.html"&gt;couldn't find a free and easy way to get started&lt;/a&gt;, so I &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-java.html"&gt;turned to Java&lt;/a&gt; instead.  The Java documentation on Sun&amp;rsquo;s site is nice.  For example, take a look at their &lt;a href="http://java.sun.com/docs/books/tutorial/2d/TOC.html"&gt;Java 2D documentation&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
After playing with it for half a day, I have an applet that lets me build roads.  One of the most confusing things was figuring out how to write &amp;lt;object&amp;gt; and &amp;lt;applet&amp;gt;.  Ick.  (Let me know if it doesn&amp;rsquo;t work for you.)
&lt;/p&gt;
    &lt;object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" 
              codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab#Version=1,4,0,0"
              height="300" width="500" &gt;
        &lt;param name="code" value="World" /&gt;
        &lt;param name="archive" value="http://theory.stanford.edu/~amitp/game-programming/road-applet/world.jar" /&gt;
        &lt;param name="type" value="application/x-java-applet;jpi-version=1.4" /&gt;
        &lt;param name="GRIDSIZE" value="30" /&gt;
        &lt;!--[if !IE]&gt; Mozilla/Netscape and others will use inner object --&gt;
        &lt;object classid="java:World.class" 
                archive="http://theory.stanford.edu/~amitp/game-programming/road-applet/world.jar" 
                height="300" width="500" &gt;
          &lt;param name="GRIDSIZE" value="30" /&gt;
          &lt;strong&gt;
            This browser does not have a Java Plug-in.
            &lt;br /&gt;
            &lt;a href="http://java.sun.com/products/plugin/downloads/index.html"&gt;
              Get the latest Java Plug-in here.
            &lt;/a&gt;
          &lt;/strong&gt;
        &lt;/object&gt;
        &lt;!-- &lt;![endif]--&gt;
      &lt;/object&gt;
&lt;p&gt;
The basic idea is that roads (or rails) should be between &lt;em&gt;edges&lt;/em&gt;, not &lt;em&gt;tiles&lt;/em&gt;.  Road segments are &lt;a href="http://en.wikipedia.org/wiki/B%E9zier_curve"&gt;cubic splines&lt;/a&gt; between two edges.  It&amp;rsquo;s a little tricky to select the right edge; I need to think about that problem a little bit more.  There&amp;rsquo;s a larger version &lt;a href="http://theory.stanford.edu/~amitp/game-programming/road-applet/roads.html"&gt;on my other page&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
This building UI isn&amp;rsquo;t directly usable for games like Locomotion.  It would need length and angle constraints, diagonals, bridges, and tunnels.  To make it more usable, I need to add pathfinding, so that you can drag across the grid and it will figure out which segments need to be built.  I will probably get bored before finishing all of that, though.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-109928753795120263?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/109928753795120263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=109928753795120263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/109928753795120263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/109928753795120263'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2004/10/road-building-applet.html' title='Road building applet'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-109920664093977990</id><published>2004-10-30T23:58:00.000-07:00</published><updated>2004-11-27T18:45:46.870-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Web languages: Java</title><content type='html'>&lt;p&gt;
Given &lt;a href="http://simblob.blogspot.com/2004/10/web-languages-flash.html"&gt;my failure to get started writing Flash code&lt;/a&gt;, I decided to try Java.  I downloaded Java 5.0 (which comes after 1.4, believe it or not) and &lt;a href="http://www.eclipse.org/"&gt;Eclipse 3.0&lt;/a&gt;.  Both of those sites need to have a much easier way to download the software.  Java led me down a maze of multiple versions, marketing material, and legalese.  Eclipse led me to a page of international mirrors, none of them useful (when I clicked on them, I got a big file listing and had no idea what I needed to download).
&lt;/p&gt;
&lt;p&gt;
Despite some glitches (like some dialog boxes being blank and some being far wider than the screen), I got a simple applet running.  My next step is to learn how to draw lines on the screen so that I can start creating a small isometric map.  After that I need to learn how mouse events work so that I can let the player select tiles on the map.
&lt;/p&gt;
&lt;p&gt;
The main disadvantages of Java compared to Flash are: it&amp;rsquo;s not as widespread, and it appears to be a more verbose and cumbersome language.  I'd really like to do something with Java3D, but it looks like that is not installed by default on anyone&amp;rsquo;s machine.  I just installed Java and I don&amp;rsquo;t have Java3D.  I don&amp;rsquo;t want to ask my readers to install new software just to look at my demos.  I think Java3D would be much more popular if it were installed by default.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; I&amp;rsquo;m not the only one who had &lt;a href="http://simon.incutio.com/archive/2004/11/27/eclipse"&gt;trouble downloading Eclipse&lt;/a&gt;.
&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5052387-109920664093977990?l=simblob.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simblob.blogspot.com/feeds/109920664093977990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5052387&amp;postID=109920664093977990' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/109920664093977990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5052387/posts/default/109920664093977990'/><link rel='alternate' type='text/html' href='http://simblob.blogspot.com/2004/10/web-languages-java.html' title='Web languages: Java'/><author><name>Amit</name><uri>http://www.blogger.com/profile/12159325271882018300</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_kV9ZnGnZL7M/TM2pLUy7aqI/AAAAAAAAD98/b4D2THaPBhM/s1600-R/red_blob.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5052387.post-109918732666878301</id><published>2004-10-30T18:12:00.000-07:00</published><updated>2009-03-08T22:57:03.358-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>God Games: Locomotion</title><content type='html'>&lt;p&gt;
I got Chris Sawyer&amp;rsquo;s Locomotion two weeks ago.  I love Transport Tycoon.  I have played several games in the same genre (Transport Giant, Railroad Tycoon, Roller Coaster Tycoon, etc.).  Here are my thoughts after playing roughly 10 scenarios of Locomotion.  I don&amp;rsquo;t just want to complain about the game.  I do enjoy playing it.  It&amp;rsquo;s just that there are some things that I think would make it much more enjoyable.
&lt;/p&gt;
&lt;ul class=spaced&gt;
&lt;li&gt;
&lt;strong&gt;Summaries.&lt;/strong&gt; I like the summary views: lists of stations, towns, trains, trams, planes, etc.  In my &lt;a href="http://simblob.blogspot.com/2004/07/god-games-transport-giant.html"&gt;post about Transport Giant&lt;/a&gt;, I mentioned that it was really inconvenient to get any summaries.  Locomotion is much better.  You can sort the lists too.  Minor suggestion: it would be nice if the list sort order was preserved, so you don&amp;rsquo;t have to re-sort when you re-open the list.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pathfinding.&lt;/strong&gt; Unfortunately the pathfinding is really frustrating.  There should be no need to add waypoints for trains.  Pathfinding algorithms are efficient enough, &lt;em&gt;especially&lt;/em&gt; on simple graph structures like railroads, that entire networks can be scanned easily.  Minor suggestion: for rail net
