{"id":641,"date":"2012-03-26T16:46:12","date_gmt":"2012-03-26T21:46:12","guid":{"rendered":"http:\/\/blog.red-bean.com\/sussman\/?p=641"},"modified":"2012-03-26T16:46:12","modified_gmt":"2012-03-26T21:46:12","slug":"a-graphical-text-adventure","status":"publish","type":"post","link":"http:\/\/blog.red-bean.com\/sussman\/?p=641","title":{"rendered":"A (Graphical!) Text Adventure"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/narrow-your-eyes.googlecode.com\/hg\/nye%20Materials\/Cover.png\" width=\"350\" height=\"350\"\/><\/p>\n<p>It&#8217;s that time of year again &#8212; when <a href=\"http:\/\/blog.templaro.com\/\">Jack<\/a> and I write another open-source text adventure together!<\/p>\n<p>Every time we do a project like this, we try to push our own boundaries and try something new.  <a href=\"http:\/\/code.google.com\/p\/rovers-day-out\/\">Rover&#8217;s Day Out<\/a> was our first full-length work and was our first foray into taking advantage of the deeper features of the <a href=\"http:\/\/www.inform7.com\/\">Inform7<\/a> programming language.  Our second work, <a href=\"http:\/\/code.google.com\/p\/hoosegow\/\">Hoosegow<\/a>, was an attempt to create humorous and relevant non-player characters in a constrained environment.  Our third work was a quickie challenge &#8212; we wrote 95% of <a href=\"http:\/\/code.google.com\/p\/loap\/\">Lobsters on a Plane<\/a> in a single day for a &#8216;speed&#8217; competition.<\/p>\n<p>Our fourth and latest work, <a href=\"http:\/\/code.google.com\/p\/narrow-your-eyes\/\">Narrow Your Eyes<\/a>, was written as part of a <a href=\"http:\/\/pr-if.org\/event\/apollo-18\/\">&#8216;tribute&#8217; collection<\/a> for the 20th anniversary of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Apollo_18_(album)\">Apollo 18 album<\/a> by They Might Be Giants.  There&#8217;s a short interactive fiction game written for each album track, and I suggest you go play them all!<\/p>\n<p>In this game, we decided to push the boundaries of the <a href=\"http:\/\/www.eblong.com\/zarf\/glulx\/\">Glulx<\/a> interpreter a bit by creating a puzzle that requires graphics and utilizes sound.  It sounds a bit heretical, but we assure you that there is still important textual accompaniment to the graphics portion.  For this reason, the game isn&#8217;t yet playable in a web browser.  You&#8217;ll need to download a suitable interpreter for your operating system:  either <a href=\"http:\/\/ccxvii.net\/spatterlight\/download\/spatterlight-0.5.0.zip\">Spatterlight<\/a> for Mac, <a href=\"http:\/\/mirror.ifarchive.org\/if-archive\/programming\/glulx\/interpreters\/glulxe\/WinGlulxeInstaller.exe\">Glulxe<\/a> for Windows, or <a href=\"http:\/\/ifarchive.flavorplex.com\/indexes\/if-archiveXinterpreters-multiXgargoyle.html\">Gargoyle<\/a> for Linux.  You can grab the game itself from our <a href=\"http:\/\/code.google.com\/p\/narrow-your-eyes\/downloads\/list\">downloads<\/a> page and open it with the interpreter.  Once you start, don&#8217;t forget to turn on your speakers!<\/p>\n<p>Another challenge this game was an attempt to write some basic artificial intelligence (AI) algorithms in the Inform 7 language.  If you&#8217;ve already played the game, you can read about that in the spoiler below.<\/p>\n\n<div class='easySpoilerWrapper' style=''>\n<table class='easySpoilerTable' border='0' style='text-align:center;' align='center' bgcolor='FFFFFF' >\n\n<tr style='white-space:normal;'>\n<th class='easySpoilerTitleA' style='white-space:normal;font-weight:normal;text-align:left;vertical-align:middle;font-size:120%;color:#000000;'>Spoiler Inside<\/th>\n<th class='easySpoilerTitleB'style='text-align:right;vertical-align:middle;font-size:100%; white-space:nowrap;'><a href='' onclick='wpSpoilerSelect(\"spoilerDiv332a8001\"); return false;' class='easySpoilerButtonOther' style='font-size:100%;color:#000000;background-color:#fcfcfc;background-image:none;border: 1px inset;border-style:solid;border-color:#cccccc; margin: 3px 0px 3px; padding: 4px; ' align='right'>Select<\/a><a href='' onclick='wpSpoilerToggle(\"spoilerDiv332a8001\",true,\"Show\",\"Hide\",\"fast\",false); return false;' id='spoilerDiv332a8001_action' class='easySpoilerButton' value=\"Show\" align='right' style='font-size:100%;color:#000000;background-color:#fcfcfc;background-image:none;border: 1px inset;border-style:solid;border-color:#cccccc; margin: 3px 0px 3px 5px; padding: 4px;'>Show<\/><\/th>\n<\/tr>\n<tr><td class='easySpoilerRow' colspan='2' style=''><div id='spoilerDiv332a8001' class='easySpoilerSpoils'  style='display:none; white-space:wrap; overflow:auto; vertical-align:middle;'>\n<\/p>\n<p>In particular, we needed to write an algorithm that represented the mad professor sending commands to the robot.  If you look at this <a href=\"http:\/\/code.google.com\/p\/narrow-your-eyes\/source\/browse\/nye.inform\/Source\/story.ni#652\">section of the source code<\/a>, you can see our basic strategy:<\/p>\n<ul>\n<li> Create a global table of all 5 potential moves by the AI.<\/li>\n<li> Each turn, evaluate the &#8216;Goodness&#8217; of each move by figuring out where the robot would eventually end up.  The closer he is to the player&#8217;s column, the better the move.<\/li>\n<li> Update the Goodness values in the table, sort the table by Goodness, and choose the first row as the &#8216;best move&#8217; <\/li>\n<\/ul>\n<p>Of course, there are a couple of tweaks we made as well:<\/p>\n<ul>\n<li> If the robot is in the player&#8217;s column and facing him &#8212; don&#8217;t calculate a move &#8212; just fire the laser.<\/li>\n<li> If the top two moves are tied for &#8216;Goodness&#8217;, break the tie by looking at the robot&#8217;s potential facing-direction. <\/li>\n<li> If the &#8216;best move&#8217; would result in the robot ending up in the same place he is already, then make a random move.  This prevents the robot from getting stuck in a loop.<\/li>\n<\/ul>\n<p>If you&#8217;d like to play with the code, it&#8217;s abstracted to the point where you can make the floor plan as large as you want with whatever tiles you wish.  You can also use the in-game command &#8216;Allotheria&#8217; to randomize the tiles.  \ud83d\ude42<\/p>\n<p>\n<\/div><\/td><\/tr>\n<\/table>\n<div class='easySpoilerConclude' style=''><table class='easySpoilerTable' border='0' style='text-align:center;' frame='box' align='center' bgcolor='FFFFFF'><tr><th class='easySpoilerEnd' style='width:100%;'><\/th><td class='easySpoilerEnd' style='white-space:nowrap;' colspan='2'><\/td><\/tr><tr><td class='easySpoilerGroupWrapperLastRow' colspan='2' style=''><\/td><\/tr><\/table><\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s that time of year again &#8212; when Jack and I write another open-source text adventure together! Every time we do a project like this, we try to push our own boundaries and try something new. Rover&#8217;s Day Out was our first full-length work and was our first foray into taking advantage of the deeper [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-641","post","type-post","status-publish","format-standard","hentry","category-interactive-fiction"],"_links":{"self":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=641"}],"version-history":[{"count":15,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/641\/revisions"}],"predecessor-version":[{"id":657,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/641\/revisions\/657"}],"wp:attachment":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=641"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}