tag:blogger.com,1999:blog-4367913461411052602024-03-13T03:36:03.350-07:00Remote Shepherd Developer's BlogBradley Blankenshiphttp://www.blogger.com/profile/04192181661889878626noreply@blogger.comBlogger41125tag:blogger.com,1999:blog-436791346141105260.post-53140715581702985732011-06-05T20:54:00.000-07:002011-06-05T20:55:43.398-07:00<iframe width="425" height="349" src="http://www.youtube.com/embed/gBzJGckMYO4" frameborder="0" allowfullscreen></iframe>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-3506557180852731432011-05-11T22:39:00.000-07:002011-05-13T13:54:07.314-07:00Dave McKean Should Be Flattered, Right? Right?So, what do you do when your game is a week from the final deadline and you realize you want some cool promotional art, splash screens and loading screens? Why, you task it to your AI engineer! Wait, why doesn't that sound right? Anyways, when I thought about what these images should look like, my mind immediately went to one of my favorite artists, who has done album covers and comic covers: Dave McKean. I had three images in particular of his in my mind when creating the images for our game:<br /><br /><div style="text-align: center;"><a href="http://3.bp.blogspot.com/-9wnBIw_0BKE/Tct80th7pMI/AAAAAAAAACU/F0OdugxPgxQ/s1600/1710_400x600.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 214px; height: 320px;" src="http://3.bp.blogspot.com/-9wnBIw_0BKE/Tct80th7pMI/AAAAAAAAACU/F0OdugxPgxQ/s320/1710_400x600.jpg" alt="" id="BLOGGER_PHOTO_ID_5605711406209672386" border="0" /></a><span style="font-style: italic;">The Sandman Vol. 7 Cover<br /><br /><br /></span><a href="http://2.bp.blogspot.com/-6kn1PH0KKy8/Tct849ZRkgI/AAAAAAAAACc/7PhV3GGWkeA/s1600/Alice_Cooper_-_The_Last_Temptation.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 320px;" src="http://2.bp.blogspot.com/-6kn1PH0KKy8/Tct849ZRkgI/AAAAAAAAACc/7PhV3GGWkeA/s320/Alice_Cooper_-_The_Last_Temptation.jpg" alt="" id="BLOGGER_PHOTO_ID_5605711479187804674" border="0" /></a><span style="font-style: italic;">The Last Temptation album cover, also the cover of Book I of The Last Temptation Comic<br /><br /><br /></span><a href="http://1.bp.blogspot.com/-Y5FOKgQNxLk/Tct89_GwTyI/AAAAAAAAACk/EB3ZP8CLn6M/s1600/TLTbook3.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 213px; height: 320px;" src="http://1.bp.blogspot.com/-Y5FOKgQNxLk/Tct89_GwTyI/AAAAAAAAACk/EB3ZP8CLn6M/s320/TLTbook3.jpg" alt="" id="BLOGGER_PHOTO_ID_5605711565546344226" border="0" /></a><span style="font-size:85%;"><span style="font-style: italic;">Cover of Book III of The Last Temptation comic</span></span><br /><br /><div style="text-align: left;"><span style="font-size:100%;">The </span>middle image hangs on my wall as a large print. With those images in mind I created:<br /><br /><div style="text-align: center;"><a href="http://4.bp.blogspot.com/-LKlyeIYO5V8/Tct-MUTxvrI/AAAAAAAAACs/nmRxswgpqmU/s1600/frontCover.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 227px; height: 320px;" src="http://4.bp.blogspot.com/-LKlyeIYO5V8/Tct-MUTxvrI/AAAAAAAAACs/nmRxswgpqmU/s320/frontCover.png" alt="" id="BLOGGER_PHOTO_ID_5605712911267905202" border="0" /></a><span style="font-style: italic;">Remote Shepherd comic book cover<br /><br /><br /></span></div><div style="text-align: center;"><a href="http://4.bp.blogspot.com/-UUpfIW9UbNM/Tct-0vnMFDI/AAAAAAAAAC0/_RBMOKkzcJo/s1600/opening.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 180px;" src="http://4.bp.blogspot.com/-UUpfIW9UbNM/Tct-0vnMFDI/AAAAAAAAAC0/_RBMOKkzcJo/s320/opening.png" alt="" id="BLOGGER_PHOTO_ID_5605713605791847474" border="0" /></a><span style="font-size:85%;"><span style="font-style: italic;">Remote Shepherd splash screen</span></span><br /><br /><br /><div style="text-align: center;"><a href="http://3.bp.blogspot.com/-Z8sdiDHF0Ow/Tct_UTy4E7I/AAAAAAAAAC8/Kb2zZPfEdXY/s1600/loading_N.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 180px;" src="http://3.bp.blogspot.com/-Z8sdiDHF0Ow/Tct_UTy4E7I/AAAAAAAAAC8/Kb2zZPfEdXY/s320/loading_N.png" alt="" id="BLOGGER_PHOTO_ID_5605714148080489394" border="0" /></a><span style="font-style: italic;">Remote Shepherd loading screen</span><br /></div></div></div></div>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com2tag:blogger.com,1999:blog-436791346141105260.post-12275830971257835082011-04-21T14:59:00.000-07:002011-04-21T15:46:53.325-07:00Havok, Vertex Buffers, Maya 2011<!--[if gte mso 9]><xml> <w:worddocument> <w:view>Normal</w:View> <w:zoom>0</w:Zoom> <w:trackmoves/> <w:trackformatting/> <w:punctuationkerning/> <w:validateagainstschemas/> <w:saveifxmlinvalid>false</w:SaveIfXMLInvalid> <w:ignoremixedcontent>false</w:IgnoreMixedContent> <w:alwaysshowplaceholdertext>false</w:AlwaysShowPlaceholderText> <w:donotpromoteqf/> <w:lidthemeother>EN-US</w:LidThemeOther> <w:lidthemeasian>X-NONE</w:LidThemeAsian> <w:lidthemecomplexscript>X-NONE</w:LidThemeComplexScript> <w:compatibility> <w:breakwrappedtables/> <w:snaptogridincell/> <w:wraptextwithpunct/> <w:useasianbreakrules/> <w:dontgrowautofit/> <w:splitpgbreakandparamark/> <w:dontvertaligncellwithsp/> <w:dontbreakconstrainedforcedtables/> <w:dontvertalignintxbx/> <w:word11kerningpairs/> <w:cachedcolbalance/> </w:Compatibility> <w:browserlevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathpr> <m:mathfont val="Cambria Math"> <m:brkbin val="before"> <m:brkbinsub val="--"> <m:smallfrac val="off"> <m:dispdef/> <m:lmargin val="0"> <m:rmargin val="0"> <m:defjc val="centerGroup"> <m:wrapindent val="1440"> <m:intlim val="subSup"> <m:narylim val="undOvr"> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:latentstyles deflockedstate="false" defunhidewhenused="true" defsemihidden="true" defqformat="false" defpriority="99" latentstylecount="267"> <w:lsdexception locked="false" priority="0" semihidden="false" unhidewhenused="false" qformat="true" name="Normal"> <w:lsdexception locked="false" priority="9" semihidden="false" unhidewhenused="false" qformat="true" name="heading 1"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 2"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 3"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 4"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 5"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 6"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 7"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 8"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 9"> <w:lsdexception locked="false" priority="39" name="toc 1"> <w:lsdexception locked="false" priority="39" name="toc 2"> <w:lsdexception locked="false" priority="39" name="toc 3"> <w:lsdexception locked="false" priority="39" name="toc 4"> <w:lsdexception locked="false" priority="39" name="toc 5"> <w:lsdexception locked="false" priority="39" name="toc 6"> <w:lsdexception locked="false" priority="39" name="toc 7"> <w:lsdexception locked="false" priority="39" name="toc 8"> <w:lsdexception locked="false" priority="39" name="toc 9"> <w:lsdexception locked="false" priority="35" qformat="true" name="caption"> <w:lsdexception locked="false" priority="10" semihidden="false" unhidewhenused="false" qformat="true" name="Title"> <w:lsdexception locked="false" priority="1" name="Default Paragraph Font"> <w:lsdexception locked="false" priority="11" semihidden="false" unhidewhenused="false" qformat="true" name="Subtitle"> <w:lsdexception locked="false" priority="22" semihidden="false" unhidewhenused="false" qformat="true" name="Strong"> <w:lsdexception locked="false" priority="20" semihidden="false" unhidewhenused="false" qformat="true" name="Emphasis"> <w:lsdexception locked="false" priority="59" semihidden="false" unhidewhenused="false" name="Table Grid"> <w:lsdexception locked="false" unhidewhenused="false" name="Placeholder Text"> <w:lsdexception locked="false" priority="1" semihidden="false" unhidewhenused="false" qformat="true" name="No Spacing"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 1"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 1"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 1"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 1"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 1"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 1"> <w:lsdexception locked="false" unhidewhenused="false" name="Revision"> <w:lsdexception locked="false" priority="34" semihidden="false" unhidewhenused="false" qformat="true" name="List Paragraph"> <w:lsdexception locked="false" priority="29" semihidden="false" unhidewhenused="false" qformat="true" name="Quote"> <w:lsdexception locked="false" priority="30" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Quote"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 1"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 1"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 1"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 1"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 1"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 1"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 1"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 1"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 2"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 2"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 2"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 2"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 2"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 2"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 2"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 2"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 2"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 2"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 2"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 2"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 2"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 2"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 3"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 3"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 3"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 3"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 3"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 3"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 3"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 3"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 3"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 3"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 3"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 3"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 3"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 3"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 4"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 4"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 4"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 4"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 4"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 4"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 4"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 4"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 4"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 4"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 4"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 4"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 4"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 4"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 5"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 5"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 5"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 5"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 5"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 5"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 5"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 5"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 5"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 5"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 5"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 5"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 5"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 5"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 6"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 6"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 6"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 6"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 6"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 6"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 6"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 6"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 6"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 6"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 6"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 6"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 6"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 6"> <w:lsdexception locked="false" priority="19" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Emphasis"> <w:lsdexception locked="false" priority="21" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Emphasis"> <w:lsdexception locked="false" priority="31" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Reference"> <w:lsdexception locked="false" priority="32" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Reference"> <w:lsdexception locked="false" priority="33" semihidden="false" unhidewhenused="false" qformat="true" name="Book Title"> <w:lsdexception locked="false" priority="37" name="Bibliography"> <w:lsdexception locked="false" priority="39" qformat="true" name="TOC Heading"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin-top:0in; mso-para-margin-right:0in; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0in; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} </style> <![endif]--> <p class="MsoNormal" style="margin-bottom: 0.0001pt; line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">So, it's been a while since I posted. We ran into an interesting situation where we learned that Havok was exporting our referenced meshes as unique meshes within our level. This led to each mesh having its own unique vertex and index buffers. Now, with trees, paths, POIs, and other content, this led up to having <b>5600</b> unique vertex and index buffers.<br /><br />That, for lack of any better words, is a lot of content. That's also a lot of state changes between graphics calls. So, how did we fix this?<br /><br />Well, we first attempted to export our files using the Havok exporter in Maya 2011, using the <b><i>"Find Mesh Instances"</i></b> filter. This filter is supposed to remove duplicate meshes from the scene, but does not detail how it does so.<br /><br />We at first assumed that any file that was referenced in would be considered a duplicate mesh. Then, when that didn't work, and we had a 50 MB level, we tried doing reference copies. That didn't work either. Well, I then systematically attempted to figure out how <b><i>"Find Mesh Instances"</i></b> worked. Turns out, I couldn't find a way for it to work (at least not using the filter).<br /><br />But, after talking with Eric, I found a nice way around this.<br /><br />So, the solution was instead to do this:</span></p> <ol start="1" type="1"><li class="MsoNormal" style="line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">Reference in the object / model you want to use from the file of your choice.</span></li><li class="MsoNormal" style="line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">After placing your reference, select the object in the Viewer or Outliner.</span></li><li class="MsoNormal" style="line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">Go to Edit->Duplicate Special (click the square next to it to set it up)</span></li><li class="MsoNormal" style="line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">Select <b>Geometry Type</b> as <i>Instance</i> and <b>Group Under</b> as <i>World</i>.</span></li><li class="MsoNormal" style="line-height: normal;"><span style="font-size: 12pt; font-family: "Times New Roman","serif";">Click <b><i>Duplicate Special</i></b>.</span></li></ol> <p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%; font-family: "Times New Roman","serif";">What this does is creates an instance of the reference that was loaded, which has its own transforms separate of its parent. However, because it is an instance of the reference, its materials, vertex data, etc will be changed when the reference is updated. Likewise, when you execute the shortcut now, these parameters will already be set up.<br /><br />When you export using the Havok Content Tools exporter for Maya 2011, <b><i>"Find Mesh Instances"</i></b> will report not finding any duplicate meshes. However, only a single instance of the mesh will be loaded and referenced in the scene. For us, this insures we only create one index and vertex buffer per referenced mesh, greatly reducing the size of our level files and increasing run-time performance for the game.</span></p>Bradley Blankenshiphttp://www.blogger.com/profile/04192181661889878626noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-57681844994299185802011-04-16T15:18:00.000-07:002011-04-19T10:41:45.484-07:00Heatmaps!I spent the last week or so working on all the pieces I need to get set up in order to have the data needed to create a heatmap. I first had to log out the data from our game engine, which I achieved by writing all the gameplay metrics to text files. The next step was to organize all the metrics from the log files into a database. The proper way to do this is to use an SQL database, but this was going to take me too long to learn and implement. So I decided to keep using a text file to store the organized gameplay metrics.<a name='more'></a><br /><br />The next major step was to build a Maya GUI using Python that would allow me to generate my databases and generate a heatmap. It took me a day or two to learn both Python and the UI system in Maya for Python. Below is the current version of my GUI, it may not be perfect but it works.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-IXh_ZcIptDk/TaoTJ_1wjlI/AAAAAAAAAJY/T-ZDgMeEOEQ/s1600/gui.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://4.bp.blogspot.com/-IXh_ZcIptDk/TaoTJ_1wjlI/AAAAAAAAAJY/T-ZDgMeEOEQ/s400/gui.png" border="0" height="146" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Maya Python GUI</td></tr></tbody></table>The heatmap right now simply shows the location of all the AI Agents using a log scale on the heat values. I had worked on generating heatmaps with Brian May (grad student) last year, and we found that this gave us an improved visualization over a normal scale. The plan is to be able to filter the heatmap based on the checkboxes in the GUI, but that requires more tackling of Maya’s GUI system. Below is an image from Maya of the current version of the heatmap.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-ZvLzvTZalQ4/TaoVPU9KqaI/AAAAAAAAAJo/kieR20MgqiQ/s1600/heatmap.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://4.bp.blogspot.com/-ZvLzvTZalQ4/TaoVPU9KqaI/AAAAAAAAAJo/kieR20MgqiQ/s400/heatmap.png" border="0" height="292" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Maya Heatmap</td><td class="tr-caption" style="text-align: center;"><br /></td></tr></tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-85833570626259579102011-04-12T10:46:00.000-07:002011-04-19T10:42:45.270-07:00Animation State Engine and Expressive AI<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-hdYj4zTTKUA/TaSQA7dJ4iI/AAAAAAAAABw/6ccB7bLe-rg/s1600/sitting.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 180px;" src="http://3.bp.blogspot.com/-hdYj4zTTKUA/TaSQA7dJ4iI/AAAAAAAAABw/6ccB7bLe-rg/s320/sitting.jpg" alt="" id="BLOGGER_PHOTO_ID_5594754982735372834" border="0" /></a><br />Now that we have some animations the AI can start to look more interesting. No longer do they merely stop at the goal and wait to move to the next goal; they actually do something at their goal now! To further that end I developed an animation state engine. This is basically a finite state engine with each state representing an animation, and the edges representing transitional animations. It allows the AI and animation systems to be separate, and the AI system to merely tell the animation system which animation state it should be in next, and the ASE will handle picking the appropriate transitional animation and determining when to play and when to stop animations. Each agent also has a map of animation categories to specific animations, meaning different agents can easily have different "Walk" or "Idle" animations without the ASE or the AI system caring at all.Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-1292574040995146052011-04-12T10:41:00.001-07:002011-04-19T10:43:07.757-07:00This Is Why We Can't Have Nice Things, DeltaA little photoshop magic on the city map shows just how well our detective takes care of his things.<br /><a href="http://2.bp.blogspot.com/-zLqQKjq0jzc/TaSO8hShEvI/AAAAAAAAABo/iwhvyr4-QD8/s1600/Sniper%2BMap_16-9.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 180px;" src="http://2.bp.blogspot.com/-zLqQKjq0jzc/TaSO8hShEvI/AAAAAAAAABo/iwhvyr4-QD8/s320/Sniper%2BMap_16-9.png" alt="" id="BLOGGER_PHOTO_ID_5594753807480328946" border="0" /></a>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-71046461052427332502011-04-12T10:23:00.001-07:002011-04-19T10:43:47.689-07:00Two Paths Diverged in the Park (With Apologies to Robert Frost)We've had the nav mesh and path finding in for a while, I just haven't had time to make a post about it. Here's what our nav mesh looks like currently:<br /><a href="http://3.bp.blogspot.com/-M_AYbz5zI3c/TaSKv_-xoAI/AAAAAAAAABY/bq9VYLiEseg/s1600/navMeshNew.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 157px;" src="http://3.bp.blogspot.com/-M_AYbz5zI3c/TaSKv_-xoAI/AAAAAAAAABY/bq9VYLiEseg/s320/navMeshNew.jpg" alt="" id="BLOGGER_PHOTO_ID_5594749194334216194" border="0" /></a>Right now it's only the actual dirt/concrete/DG/whatever paths in the park, it doesn't include grassy areas yet. There are plans in the future to mesherize the grassy areas as well, but we need some way to assign terrain modifiers to polygons so that AI knows what kind of terrain it is walking on. The other thing you will notice about the nav mesh is that it is all triangles, instead of n-gons. This is unfortunately a shortcoming of Havok, it refuses to read anything but triangles. This means more polygons than strictly necessary, and also it means that our centroids kind of make a wobbly line. That being said, it works pretty well, and the local avoidance gets the AI to alter it's path and keeps them from looking like they are in one big line.<br /><a href="http://4.bp.blogspot.com/-VocVO4Clr1I/TaSObbYglbI/AAAAAAAAABg/sOhlaGg1KAA/s1600/navMeshINUse.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 181px;" src="http://4.bp.blogspot.com/-VocVO4Clr1I/TaSObbYglbI/AAAAAAAAABg/sOhlaGg1KAA/s320/navMeshINUse.jpg" alt="" id="BLOGGER_PHOTO_ID_5594753238959166898" border="0" /></a>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-63227976187718559702011-03-29T14:18:00.000-07:002011-04-04T09:50:46.803-07:00Scout ModeAs I mentioned in an earlier <a href="http://remote-shepherd.blogspot.com/2011/03/game-modes-huds.html">post</a> we created a new game mode called Scout where the player views through a camera and has a directional microphone. The first thing to notice the HUD is designed to match what the player would see while looking through the viewfinder on high end digital camera. The squares and circle have no bearing in our game, but are there to simply match what would be seen through a real camera's viewfinder.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-oL_JHXOUTXI/TZI-z0o0_bI/AAAAAAAAAIk/zo9rlWiEC-c/s1600/Scout_HUD.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://4.bp.blogspot.com/-oL_JHXOUTXI/TZI-z0o0_bI/AAAAAAAAAIk/zo9rlWiEC-c/s400/Scout_HUD.png" border="0" height="225" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Scout HUD</td></tr></tbody></table><a name='more'></a>The only element that remains from the shooter mode is the compass that is there so the player can now where they are facing. All the elements for the scope have been removed because you are no longer looking through a rifle scope. The character dialogue areas have also been removed because the player in this mode has noise canceling headphones on to focus on the sound picked up by the mic.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-SyFz_iV_W1M/TZJLeQEThBI/AAAAAAAAAI0/k5UWSiE92SY/s1600/HUD_16-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://4.bp.blogspot.com/-SyFz_iV_W1M/TZJLeQEThBI/AAAAAAAAAI0/k5UWSiE92SY/s400/HUD_16-9.png" border="0" height="225" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Dialogue Bubbles</td></tr></tbody></table>The image above demonstrates how the dialogue that is picked up by the directional mic is presented to the player. We spent a week discussing several ways in which we could present the dialogue to the player. We finally settled on using comic book bubbles to keep all dialogue consistent throughout the entire game. With this approach we did lose the ability to lower the volume of noise on the edge of the mic’s range which he cleverly got around. As a voice becomes quiter we replace more and more characters in the dialogue with random characters. Then the location of each bubble is randomly selected as any locational information is lost when using a directional mic.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-37063007097245615192011-03-29T12:34:00.000-07:002011-03-29T12:49:23.357-07:00Making Comic Book UIsOne of my jobs on this project is as UI design which has been challenging because of the comic book look of the game. All of the Menus and HUDs have to look like something a reader might find in a comic book. As such I have to find some reference material on panel layout, lettering and art styles. If anyone is interested in any of these topics here are a few places to look at.<br />
<ul><li>A must read for comics would be <a href="http://www.scottmccloud.com/2-print/1-uc/index.html">Understanding Comics</a> by Scott McCloud.</li>
<li>A great reference for lettering traditions is <a href="http://www.blambot.com/grammar.shtml">Comic Book Grammar and Tradition</a>.</li>
<li>A very helpful adobe illustrator tutorial for comic book lettering by Jim Campbell, <a href="https://files.me.com/jim.campbell/qqt5ck">https://files.me.com/jim.campbell/qqt5ck</a>.</li>
</ul>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-88598221492297464882011-03-29T10:39:00.000-07:002011-04-04T09:49:23.034-07:00Sniper MapOne of the new features that came out of the redesign of the missions is that there are now more sniper nests than snipers. This means that the player will be able to reposition the snipers around the mission area. So we had to come up with a system to allow the player to control the position of the snipers and luckily one of the games we looked at during the research phase of the game had such a system. It had stuck with me as it seemed to be a simple solution that added a new menu page and keep the controls simple. <br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-3UnMfI7Q_Cc/TZIWKXSyf9I/AAAAAAAAAIc/OdOwunarJpI/s1600/The%2BStrangers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://4.bp.blogspot.com/-3UnMfI7Q_Cc/TZIWKXSyf9I/AAAAAAAAAIc/OdOwunarJpI/s400/The%2BStrangers.png" border="0" height="226" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The Strangers</td></tr></tbody></table><a name='more'></a>The flash game <a href="http://arcadevoid.com/play/the-strangers">The Strangers</a> gave the player two snipers that could move around to four sniping positions. To do this the game had a special menu that showed a map of the world, each sniper with their field of view and each position. When the player mouse’s over an empty position they can see that position’s field of view and two buttons representing each sniper. To move a sniper the player must mouse over an empty position and then click the button for which sniper they want to move here. Then while a sniper is in transition the player sees a progress bar under the position they are moving to; the player cannot do anything with that sniper until they reach their destination.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-bW5ZLcUV67o/TZIS9IXcJuI/AAAAAAAAAIU/DSKjo_qRRpM/s1600/Sniper%2BMap_16-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://1.bp.blogspot.com/-bW5ZLcUV67o/TZIS9IXcJuI/AAAAAAAAAIU/DSKjo_qRRpM/s400/Sniper%2BMap_16-9.png" border="0" height="225" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Remote Shepherd</td></tr></tbody></table>There were a few things that I felt could have been done better in our implementation of the move sniper menu. The most obvious change is that I made the map look like a physical road map and gave each sniper element a hand drawn look. We did this to give the menu a gritty comic book look and feel unlike the digital look of The Strangers’ version. The other changes were made to the controls of how the player got to this menu and how they interact with the map.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-24087684457144417392011-03-26T19:08:00.000-07:002011-04-09T07:41:24.773-07:00Game Modes / HUDsThis past week we established two play modes for our game, Shooter and Scout. The Shooter mode is the original mechanic of the game where the player uses a rifle and a scope to locate their target and kill them for lethal conclusions. Below is the first version of the HUD for this game mode. In the center is what the sniper sees looking through the scope of their rifle. Around the scope the player can see their current setting for the scope's magnification, elevation adjustment, windage adjustment and a compass to show where they are facing. Then in each corner of the screen there is a designated area for each of the snipers (Alpha, Foxtrot and Whiskey) and the police detective (Delta) to talk.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-irfl6HMmkfk/TY6SN6Np9hI/AAAAAAAAAH8/Bt8ib0Itxfw/s1600/HUD_16-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="http://1.bp.blogspot.com/-irfl6HMmkfk/TY6SN6Np9hI/AAAAAAAAAH8/Bt8ib0Itxfw/s400/HUD_16-9.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Shooter Mode</td></tr>
</tbody></table><br />
The new game mode is Scout where the player uses a directional mic attached to a high power camera. The player will use the mic as another method of locating their target and the camera to gather evidence for non-lethal conclusions. In this mode dialogue picked up by the mic is displayed in radio bubbles around in the blacked area of the HUD. Due to how the dialogue is displayed, we removed everything but the compass form the Shooter mode HUD.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-LznUSNYISM8/TY6XI84rpVI/AAAAAAAAAIM/hav60TzWlrk/s1600/HUD_L_16-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="http://3.bp.blogspot.com/-LznUSNYISM8/TY6XI84rpVI/AAAAAAAAAIM/hav60TzWlrk/s400/HUD_L_16-9.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Scout Mode</td></tr>
</tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-70787389157910158242011-03-26T11:13:00.000-07:002011-03-26T12:07:53.885-07:00Repurpose Not RebuildAs a follow up to my earlier post about scraping our designed levels and building a new one it is important to mention that for the mission redesign we first designed the mission situation and then placed that situation into an environment. This let us build a gameplay experience that would be fun and engaging for our player, which was why we scrapped the first missions in the first place. It also allowed us to make the environment be something that we could use as much of the art assets we had gotten for our art team as we could. As well as keeping old art assets and making the game more fun it was equally important that we redesign the narrative. Mainly because at the time we were unsure how many artists we still had on our art team and Dan and myself would not be able to make enough of the assets we needed. It was also important because all the art we had worked well and there was no need to scrap any of it.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-24940115445976532612011-03-26T11:00:00.000-07:002011-03-27T08:01:25.105-07:00Building a TerrainOne new problem with the redesign of the game's narrative path is that the park is not a flat plane like the market was. This meant we would have to generate a terrain in Maya, which is something difficult for myself to do as the level designer. After a week's worth of searching for plug-ins or external software that would let me design the terrain of the park I decided on the program that would best allow me to generate a terrain and export it into Maya: <a href="http://nemesis.thewavelength.net/index.php?p=8">Nem's Mega 3D Terrain Generator</a>. <br />
<br />
After experimenting with all the other solutions I had found, I settled on Nem's Mega 3D Terrain Generator for several reasons. The most important was that it allowed the level designer to quickly generate a terrain using some built-in generation techniques and hand-sculpting tools. This program also allows us to export our terrain as an .OBJ files that we can then import into our Maya scenes, a feature I felt was important to have. The designer also has control of the size and number of triangles of the terrain, which is important for us to make sure we keep our poly count down. Lastly with Nem's Terrain Generator the designer can hand paint each face with a texture which is nicer than Maya's process for applying a face with a particular texture.<br />
<table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-rN0Bw6Fuc_A/TYprbBaOlyI/AAAAAAAAAHw/9CaWtOvDgQo/s1600/Untitled.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://3.bp.blogspot.com/-rN0Bw6Fuc_A/TYprbBaOlyI/AAAAAAAAAHw/9CaWtOvDgQo/s400/Untitled.png" border="0" height="239" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Nem's Mega 3D Terrain Generator</td></tr>
</tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com2tag:blogger.com,1999:blog-436791346141105260.post-40889972320348656662011-03-25T13:55:00.000-07:002011-03-26T19:19:55.326-07:00The World is Not A Round, Spherical PlaceAI characters need a way to get around the world, and we considered three ways to let them do this. The first was local avoidance, but this can very easily devolve into dithering unless the level is specifically designed to prevent it. As such we decided to do actual path finding, the only decision left being whether to use a node graph or a navigation mesh. We decided to go with a navigation mesh based on the recommendations of <a href="http://www.ai-blog.net/archives/000152.html">this</a> article. I'll summarize the relevant points here.<br />
<a name='more'></a><br />
Using path nodes would require the traversable space of the world to be defined either by 1-dimensional points or circular areas defined as radii from a 1-dimensional point. Which means an area like this:<br />
<a href="http://3.bp.blogspot.com/-zrphiq-c9mc/TY0HfzRw5vI/AAAAAAAAAAw/CMor5ehH5oc/s1600/park.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5588130955558708978" src="http://3.bp.blogspot.com/-zrphiq-c9mc/TY0HfzRw5vI/AAAAAAAAAAw/CMor5ehH5oc/s320/park.jpg" style="cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>Would have to be defined either like this:<br />
<a href="http://1.bp.blogspot.com/-J989XtZX2k0/TY0NnXdI5AI/AAAAAAAAAA4/_PKDWGWuRHw/s1600/pathNodes_emptySpace.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5588137682598945794" src="http://1.bp.blogspot.com/-J989XtZX2k0/TY0NnXdI5AI/AAAAAAAAAA4/_PKDWGWuRHw/s320/pathNodes_emptySpace.jpg" style="cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>or like this:<br />
<a href="http://3.bp.blogspot.com/-Z7fQ4qwuKig/TY0O31VwtgI/AAAAAAAAABA/19ppQ5BsAtc/s1600/pathNodes_many.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5588139065010599426" src="http://3.bp.blogspot.com/-Z7fQ4qwuKig/TY0O31VwtgI/AAAAAAAAABA/19ppQ5BsAtc/s320/pathNodes_many.jpg" style="cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>I'm not even going to try to draw all the edges on that one. The problem with the second method should be obvious: there are far too many path nodes. But using so many overlapping path nodes is the only way to cover all the space that we want to be traversable using circles. The packing efficiency of circles sucks. And if there are too many nodes, there are way, way too many edges. The problem with the first solution is that it doesn't cover all the traversable terrain (again, packing efficiency sucks). Which means, even if we let the AI off of pathfinding when it is in radius of a path node, there is still plenty of space where it is stuck on a single line path.<br />
<br />
Now, the same area defined with a navigation mesh would look like this:<br />
<a href="http://3.bp.blogspot.com/-KyNofsxrGOI/TY0WerNpZII/AAAAAAAAABI/0redgsG0_tk/s1600/navMesh.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5588147428888503426" src="http://3.bp.blogspot.com/-KyNofsxrGOI/TY0WerNpZII/AAAAAAAAABI/0redgsG0_tk/s320/navMesh.jpg" style="cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>Our navigation mesh has 36 polygons, and covers much more of the traversable area than our many path nodes method, which had 44 path nodes. And as long as we only use convex polygons it's almost trivial to determine if the AI is within a polygon, and which one. We can still do all the interesting stuff that path nodes can, such as applying weight modifiers to certain polygons or running A* on it, pretty much anything we can do with path nodes we can do with a navigation mesh. We can even put paths within the navigation mesh that may have affinity modifiers, such as a sidewalk that people may prefer to walk on rather than the grass, which would reduce the cost of the using those polygons in an A* algorithm.<br />
<a href="http://4.bp.blogspot.com/-HugbS37QHsc/TY0YzfJz9WI/AAAAAAAAABQ/WEZeNFE5GPQ/s1600/navMesh_internalPath.jpg"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5588149985451701602" src="http://4.bp.blogspot.com/-HugbS37QHsc/TY0YzfJz9WI/AAAAAAAAABQ/WEZeNFE5GPQ/s320/navMesh_internalPath.jpg" style="cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-4335437051183413142011-03-20T11:26:00.000-07:002011-03-20T11:46:57.630-07:00Not The Man I Used To BeAs you know, Remote Shepherd has had a reboot of sorts. What this means for AI is essentially starting over on character design. Previously we had five types of AI planned for the first level (the Market Mission): three different kinds of shopkeepers who would resist the debt collector to varying degrees, regular people just out shopping, and the debt collector himself. While all the designs for the AI characters were finished I had fortunately only implemented the shopper in code.<br /><br /><div style="text-align: center;"><a href="http://4.bp.blogspot.com/-WehJ61uZbp4/TYZIQLDfeAI/AAAAAAAAAAg/ZBsH37SfdwA/s1600/Photo0065.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/-WehJ61uZbp4/TYZIQLDfeAI/AAAAAAAAAAg/ZBsH37SfdwA/s320/Photo0065.jpg" alt="" id="BLOGGER_PHOTO_ID_5586231830482221058" border="0" /></a><span style="font-size:85%;"><span style="font-style: italic;">Behavior trees and finite state engines for the original AI characters<br /><br /></span></span><div style="text-align: left;"><span style="font-size:85%;"><span style="font-size:100%;">In addition to the problems Eric mentioned in his post, the original design of the second and third missions was incredibly vague in terms of AI and behaviors, and trying to come up with AI to fit the environment and narrative wasn't working ("So what'll be the NPCs be doing in Mission 2?" "Uhhh"). With the new park environment we have a much larger pool of behaviors that people might engage in in that space, and the hard part became trimming the list to behaviors that </span></span>served our gameplay purpose: to act as a red herring. This trimming is just a prioritization though, not a deletion of any behaviors. The game will also need AI characters that are not red herrings, but are there to flesh out the environment and make it seem realistic and alive. The three characters (in addition to the unique target characters) that we have prioritized are: The Reader, The Walker, and The Jogger.<br /><br /><div style="text-align: center;"><a href="http://4.bp.blogspot.com/-4C5ONVoHxeY/TYZK9QSuRrI/AAAAAAAAAAo/0e0a6JWx80A/s1600/Photo0069.jpg"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/-4C5ONVoHxeY/TYZK9QSuRrI/AAAAAAAAAAo/0e0a6JWx80A/s320/Photo0069.jpg" alt="" id="BLOGGER_PHOTO_ID_5586234804005652146" border="0" /></a><span style="font-size:85%;"><span style="font-style: italic;">Sample of behavior trees and finite state engines for The Reader, The Jogger, The MobGuy and The BodyGuard<br /></span></span></div></div></div>Dan Wilsonhttp://www.blogger.com/profile/01624255472370023345noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-25174254040412211212011-03-19T12:17:00.001-07:002011-03-25T10:06:01.018-07:00The Soundscape (First Design)The Soundscape for this game will be similar to the Central Park in NYC or the Middle Park in GTA IV. <div><br /><div>The types of sound that can be heard in public parks are as following :- </div><ul><li>Birds</li><li>Sounds of Nature</li><li>People/Crowd </li><li>Vehicle/Traffic</li><li>Music</li><li>Air Traffic</li><li>Machines<br /></li></ul><div>Below is the first design for the Soundscape of the game's level.<br /><br /></div></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-e3ROjRXkIFM/TYzLEgQ_E8I/AAAAAAAAACI/M5FGe4ozX2k/s1600/Soundscape.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://4.bp.blogspot.com/-e3ROjRXkIFM/TYzLEgQ_E8I/AAAAAAAAACI/M5FGe4ozX2k/s320/Soundscape.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5588064515901035458" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-31mtiH04BGU/TYzKbMaEH8I/AAAAAAAAACA/gIQh5L7oVLA/s1600/Soundscape2.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://3.bp.blogspot.com/-31mtiH04BGU/TYzKbMaEH8I/AAAAAAAAACA/gIQh5L7oVLA/s320/Soundscape2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5588063806195769282" /></a>Farhanhttp://www.blogger.com/profile/18086211197854881405noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-61058228206629887632011-03-18T13:18:00.000-07:002011-03-27T08:03:48.903-07:00Paramount Park ConceptThe new mission for Remote Shepherd takes place in a large park in the center of the downtown borough of River Ridge. The design of the park is heavily influenced by both Central Park in NYC and Middle Park in GTA IV. For our level the Central Park was too large for us to recreate with our time limit and the layout of Middle Park did not match well with what we needed out of the space for our game.<br />
<a name='more'></a><br />
Using these two versions of the same type of space I began building the layout for our level. I started by looking through both parks and making a list of point of interests I found. The next step was to narrow this list down to areas that would enhance the NPCs' behaviors found in this mission. Once I narrowed the list down to about eight POIs I started playing around with how I could lay them out. The end result of this can be seen in the image at the bottom of this post.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-oc4aMW4fzTY/TYOmoMiq2-I/AAAAAAAAAHc/u5-RmOWOaJw/s1600/middlepark.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="http://4.bp.blogspot.com/-oc4aMW4fzTY/TYOmoMiq2-I/AAAAAAAAAHc/u5-RmOWOaJw/s400/middlepark.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Middle Park, GTA IV</td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-QMDcU9F3MDM/TYOmnyAm98I/AAAAAAAAAHU/xmrdF1DNMRI/s1600/christo_central_park4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="300" src="http://3.bp.blogspot.com/-QMDcU9F3MDM/TYOmnyAm98I/AAAAAAAAAHU/xmrdF1DNMRI/s400/christo_central_park4.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Central Park, NYC</td></tr>
</tbody></table>The blue areas are a large pond and a stream that runs through the park. The thin black lines represent walking paths. The thick black line with yellow dashes represents a road that splits the park into two distinct zones. The POIs are designated with red areas.<br />
<ul><li>BP = Benched path</li>
<li> BD = Board game</li>
<li>Fo = Food Court</li>
<li>Fn = Fountain</li>
<li>G = Gazebo</li>
<li>A = Art path</li>
</ul><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-mo_uC9XQIfs/TYO3auxA5PI/AAAAAAAAAHo/JenlR06izZ4/s1600/Park_Layout.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="http://4.bp.blogspot.com/-mo_uC9XQIfs/TYO3auxA5PI/AAAAAAAAAHo/JenlR06izZ4/s400/Park_Layout.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Paramount Park Layout</td></tr>
</tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-57160650652417121702011-03-18T11:31:00.000-07:002011-03-20T10:40:08.934-07:00Mole Hunt - Mission BriefingWe (Remote Shepherd vigilante group) have been working to remove the hold organized crime has on River Ridge City for the better part of two years. We have managed to remove most of the low level gangs, but this has led to the remaining organizations working together to take us out, operating under the moniker "Wilcox-Arlington Management Group." (WAMG) One of the member crime families, we don't know which, has managed to gain one, if not more, informants inside of the RRPD. These informants are both giving police information to the crime families and manipulating the actions of the police department.<br /><br />I (Delta) have been able to obtain information that a transfer between one of the informants and an intelligence officer for WAMG is going down in Paramount Park today. I was unable to obtain any information on the informant, but was able get the files on the intelligence officer. You will have to use the intelligence officer in order to uncover the informant. The intelligence officer will be attempting to maintain a low profile but he will be accompanied by his personal bodyguard.<br /><br />Once you’ve located the intelligence officer, do not lose him. He will surely be cautious and aware that we are hunting him. You’ll also have to pay close attention to anyone near the intelligence officer as I am sure he and the informant will attempt to disguise their meeting as something else. I cannot stress enough that the goal of this mission is to stop the flow of information and the manipulation of the police department. I don’t care how you achieve this goal; just make sure you don’t screw this up.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-55379439570164158222011-03-11T08:45:00.000-08:002011-03-27T08:03:48.903-07:00Once Upon A TimeThere is a fair amount of information on the web about stories in video games. I know when I started looking for articles it was hard to find any worth reading, so I figured I'd give anyone out there a head start.<br /><br /><a href="http://www.lcc.gatech.edu/%7Ebogost/courses/spring07/lcc3710/readings/jenkins_game-design.pdf">Game Design as Narrative Architecture</a><br />Is a great article on narrative in games and environmental storytelling.<br /><br /><a href="http://www.paranoidproductions.com/">paranoidproductions.com</a><br />I would recommend anything from Richard Rouse III. “Seven Ways a Video Game Can Be Moral” and “Environmental Narrative: Your World is Your Story” are both great places to start.<br /><br /><a href="http://www.worch.com/2010/03/11/gdc-2010/">What Happened Here?</a><br />Is a great presentation on environmental storytelling.<br /><br /><a href="http://www.onethree.org/talks/">onethree.org/talks</a><br />“Player-Driven Stories: How Do We Get There?” is a great talk on ways to allow the player to branch the story and ways to let this happen that don’t kill the people making the content.<br /><br />“No Explanation Necessary: Minimizing Exposition in Game” is a great talk if you can find it somewhere on the web or in the GDC vault.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-66712051269314729252011-03-11T08:05:00.000-08:002011-03-12T11:15:38.691-08:00Hit The Redo ButtonLast week a few of us attended GDC and I managed to attend several of the sessions dealing with different aspects of a games narrative. Along with giving me tons of new information I could apply towards our game it also gave me the chance to take a step back and examine "Remote Shepherd". By the time I got back from GDC I had determined that I had made a major design mistake as far as our missions went.<br /><br />I had designed the missions first around a narrative ark and then tried to wrap gameplay around it. This left us with a story that we were unsure we could tell with a shrinking art team and a game that I did not see as fun anymore. So I had determined that we needed to scrap the missions we had designed for the story and craft a new one that was designed around the gameplay.Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-12526781599063041882011-02-24T11:19:00.000-08:002011-03-27T08:03:48.904-07:00Market Sniper Nest ConceptsBelow are two concept drawings of what players will see from two of the three sniper nests in the Market mission. The first is from a billboard on the roof of a building a few blocks away from the market square. This sniper nest gives the player a view of the north side of the market that is obstructed from the other two nests' field of view. However this sniper nest is limited to only having a clear shot of this section of the market square.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-QmDXQLn6yQs/TWaMlMxhP3I/AAAAAAAAAG4/v2hO1Mn38o8/s1600/Billboard%2BPOV.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://2.bp.blogspot.com/-QmDXQLn6yQs/TWaMlMxhP3I/AAAAAAAAAG4/v2hO1Mn38o8/s400/Billboard%2BPOV.jpeg" border="0" height="290" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Billboard Sniper Nest</td></tr></tbody></table><br />The next sniper nest is situated on the top of the stairway access to a building’s rooftop. This sniper nest has a clear view of most of the market square; it's almost the opposite of the billboard sniper nest. However this nest has a poor shot on the section of the market square directly below it due to the magnification by the sniper scope.<br /><br /><table class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;" align="center" cellpadding="0" cellspacing="0"><tbody><tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-0GUf7f8szaE/TWaMlYZEDwI/AAAAAAAAAHA/f-5NY2wzMCk/s1600/Roof%2BPOV.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img src="http://2.bp.blogspot.com/-0GUf7f8szaE/TWaMlYZEDwI/AAAAAAAAAHA/f-5NY2wzMCk/s400/Roof%2BPOV.jpeg" border="0" height="298" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Rooftop Sniper Nest</td></tr></tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com2tag:blogger.com,1999:blog-436791346141105260.post-69668028495810721822011-02-24T10:01:00.001-08:002011-02-24T10:44:32.752-08:00Sound Types and Categories<div style="text-align: justify;">In Remote Shepherd's Sound Engine, we have two types of sound. They are 2D sound and 3D sound. 2D sound does not depend on any sound emitter or sound listener. When we play 2D sound, its volume will always be the same all the time. However, for 3D sound, the attributes of the sound emitter and sound listener will affect how the 3D sound being played. When the attributes of the sound emitter or listener change, the volume of the sound may increase or decrease and the sound may pan left or right.</div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">When/Where to use 2D sound?</div><ul><li style="text-align: justify;">Main Menu</li><li style="text-align: justify;">In-game Menu</li><li style="text-align: justify;">Pause Menu</li></ul><div style="text-align: justify;"><br /></div><div style="text-align: justify;">When/Where to use 3D sound?</div><ul><li style="text-align: justify;">In game's missions or levels</li></ul><div style="text-align: justify;"><br /></div><div style="text-align: justify;">In the sound engine, the sounds are divided into four categories: Music, Ambient, Effect and Voice. We divided the sounds into these categories so that it will be easier to manage.</div><div style="text-align: justify;"><br /></div><div style="text-align: justify;">Music</div><div><ul><li style="text-align: justify;">any music coming from radio, stores, buildings or background music for the main menu or in-game menu</li></ul><div style="text-align: justify;">Ambient</div><ul><li style="text-align: justify;">any sound that comes from the environment or the atmosphere. e.g. wind, machines, generator, city</li></ul><div style="text-align: justify;">Effect</div><ul><li style="text-align: justify;">any short sound or non-looping sound effects. e.g. rifle shot</li></ul><div style="text-align: justify;">Voice</div></div><div><ul><li style="text-align: justify;">any looping or non-looping audio for the characters in the game</li></ul></div>Farhanhttp://www.blogger.com/profile/18086211197854881405noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-19935917195960603962011-02-18T09:56:00.001-08:002011-03-27T07:58:28.235-07:00Weird circle issusesDuring the process of designing the HUD for the game we discovered an interesting optical illusion. Our first version of the scope reticule was made of a cross with three circles. The circles were placed to help the player to be able to judge distance of objects that did not line up with the mil dot cross. When we placed this into the game and looked at the world we discovered that our circles did not look like circles. This is a similar illusion to <a href="http://www.michaelbach.de/ot/ang_hering/index.html">Hering Illusion</a> where lines appear to bend when lines cross them. The following image illustrates what we saw and if you look in the areas between the crosses you can see where the lines seem to bend.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-HgBCTD6Pe5w/TWZ9C2xndVI/AAAAAAAAAGo/RvVJwAEdXv0/s1600/reticle_v1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="234" src="http://3.bp.blogspot.com/-HgBCTD6Pe5w/TWZ9C2xndVI/AAAAAAAAAGo/RvVJwAEdXv0/s400/reticle_v1.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First Version</td></tr>
</tbody></table>After discovering this we had to sit down and redesign how we could give the player the same capability without having any optical illusions. In the process we also discovered that circles were displaying the wrong information with circles. This lead to the new design with corner lines showing the mil dots in 4 unit increments. This broke up with circles and let the player properly measure mil dots in the reigns away from the cross. The following image illustrates how we fixed the optical illusion with using square corner pieces.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-dhNRr--nQaI/TWZ9DKWDThI/AAAAAAAAAGw/nZevVKpn3g4/s1600/reticle_v4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="234" src="http://4.bp.blogspot.com/-dhNRr--nQaI/TWZ9DKWDThI/AAAAAAAAAGw/nZevVKpn3g4/s400/reticle_v4.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Current Version</td></tr>
</tbody></table>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com1tag:blogger.com,1999:blog-436791346141105260.post-91823140427179919952011-02-17T12:17:00.000-08:002011-02-17T15:09:56.889-08:00Remote Shepherd's Sound Engine<div align="justify">The sound engine in this game is constructed using FMOD Ex which is a low-level audio engine. FMOD Ex is one of FMOD products. It is created by Firelight Technologies. Currently, FMOD Ex supports 12 platforms. It supports Microsoft Windows, Linux, Macintosh OS X, PS2, PS3, PSP, XBOX 360 and many more. A wide range of audio formats such as AIFF, FLAC, MP3, OGG, RAW, VAG, WAV, WMA, XMA and XWMA can be used with FMOD. There are many high profile commercial games like Guitar Hero III, LittleBigPlanet, Second Life and Tomb Raider: Underworld used FMOD.</div><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.fmod.org/images/header.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 220px; height: 77px;" src="http://www.fmod.org/images/header.png" border="0" alt="" /></a><br />Why FMOD?<br /><ul><li>It supports multiple platforms and variety audio file formats.</li><li>It can be used with C++ and Visual Studio.</li><li>It is FREE to use for a non-commercial product.</li></ul><br />For more information on FMOD, check out <a href="http://www.fmod.org/" target="_blank">http://www.fmod.org/</a>Farhanhttp://www.blogger.com/profile/18086211197854881405noreply@blogger.com0tag:blogger.com,1999:blog-436791346141105260.post-41759751912985499062011-02-05T08:57:00.000-08:002011-02-05T12:51:47.167-08:00Best Sniper Locations EverThroughout the design of the levels we have brainstormed interesting places for the snipers’ vantage points. Some of these we have put into our game and others that could be used in other missions if we designed the entire game. However with brainstorming come ideas that could never work but are just too funny not to mention. So I decided I would post some of my favorite ones so far.<br />
<ol><li> In a ball pit with baby dolls attached to the ghillie suit</li>
<li> On the second level of a double decker bus</li>
<li> Inside of a hotdog stand</li>
<li> On top of a flag pole</li>
<li> Under a manhole cover</li>
</ol>Eric Bakerhttp://www.blogger.com/profile/12851966060183697805noreply@blogger.com1