tag:blogger.com,1999:blog-44701681636884260032016-12-08T08:08:00.342-05:00News of TCHOWSequential content as relates to tchow.com.Jim McCannnoreply@blogger.comBlogger122125tag:blogger.com,1999:blog-4470168163688426003.post-26420853660740121402016-05-17T22:24:00.000-04:002016-05-17T22:30:46.448-04:00Convex Horizons<p>Today, I started thinking about the complexity of a certain geometric problem: finding the horizon of a set of convex objects. In this post, I'll first state the problem and then attempt to explain why this is an interesting problem to think about. </p><h1>The Convex Horizon Problem</h1><p>Given a list of 2D convex objects, return a function h that maps each x-coordinate to the maximum y-coordinate such that (x, h(x)) is contained in some object. This is the "horizon" or "skyline" of the objects. </p><p><b>First Reduction:</b> when working with convex polygons, this is equivalent to finding the horizon of a series of line segments; or, equivalently, trapezoids with bottom edges at negative infinity. So this is the version of the problem I'll be thinking of: </p><div style="text-align:center"><img src="https://2.bp.blogspot.com/-NSQ9xj5k4tU/VzvMtmAARNI/AAAAAAAADb8/kuHJxAzxj9w3KYSYZiVjTEMG8WrFnf4fQCLcB/s1600/trapezoid-hull.png" /></div><p style="color:grey">(The horizon of the many-hued trapezoids is the thick black polyline.) </p><h1>Thoughts on Complexity</h1><p>Any algorithm that computes such a horizon must spend time at least linear in the number of output points in the horizon line. So it's interesting to think about how many points this could be. Particularly, I find this intriguing because of two different (related) problems. </p><div style="text-align:center"><img src="https://1.bp.blogspot.com/-Uhjb-KN4VuQ/VzvN26gESkI/AAAAAAAADcE/GZ4yhH6gX8Mqcl_j_2cOT9GTPaBmIjToACLcB/s1600/boxes-hull.png" /></div><p>The <b>Box Horizon</b> problem pretty clearly has output of size at most 4N (for N boxes). The argument goes something like: the horizon is a chain of line segments alternating between flat segments and vertical segments. The vertical segments correspond to the vertical edges of boxes, and each box edge appears at most once in the list. This means there are at most 2N vertical segments, which must (therefore) separate at most 2N horizontal segments. </p><p style="color:grey" >(Mind you, the time complexity of an algorithm that computes a box horizon from an unsorted set of boxes is likely O(N log N), given as reducing sorting to box horizon seems likely to be trivial.) </p><p>The logic used to argue for the output complexity of box horizon breaks for trapezoid horizon because the topmost trapezoid can switch not just at an edge, but at a line segment intersection. And it's easy to see that there can be quadratically many intersections among lines: </p><div style="text-align:center"><img src="https://3.bp.blogspot.com/-vxsCxi5Zg5I/VzvQkvRbzdI/AAAAAAAADcQ/l2HtrnaJFLgBSWuUUI1Wg4U0QZz2dlgrQCLcB/s1600/lines-intersect.png" /></div><p>But this standard lines example doesn't have a clear translation to the trapezoid horizon setting! So that leaves an interesting puzzle: is there some <b>other argument</b> that can be used to demonstrate linear output complexity of trapezoid horizon? Or, failing that, what's a <b>super-linear output complexity example</b> for this setting? </p><p>I plan to ponder this more over the next few days. If you have some ideas, feel free to <a href="http://tchow.com/about/#contact">get in touch</a>. </p> Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-84264354146586444812015-04-01T23:38:00.001-04:002015-04-01T23:38:59.614-04:00The Rktcr Benchmark<p>In preparing <a href="http://tchow.com/games/rktcr">Rktcr</a> for release on Steam, I've been making some minor adjustments to the code and art (Steam Achievements! Blinking characters!). As I've made a bit of a fuss about before, Rktcr is a game that plays <em>exactly</em> the same across three compiler/OS combinations (g++/Debian, clang++/OSX, cl.exe/Windows). As such, part of any update is confirming determinism with an extensive test suite. </p><p>Specifically, I have the game compute SHA1 hashes of relevant state as it plays itself on a hand-crafted set of ~1,600 par time paths. Yes, there are over 1,600 individual paths segments you might want to play in Rktcr, and I have a plan to add cheat-proof leaderboards for all of those. But that's a topic for another post. </p><h2>The Benchmark</h2><p>So how do my Windows and Linux partitions stack up against each-other on this (blended filesystem/compiler optimization) benchmark? (I'm not testing clang++/OSX since that's not installed on the same machine.) </p> <style>table { border-collapse: collapse; } td , th { border-bottom: 1px solid black; padding: 0em 1em; } </style> <table style="margin-left:auto; margin-right:auto"><tr style="text-align:center"><th>OS</th><th>Compiler</th><th>Time</th></tr><tr><td>Windows</td><td>VS2013, Update 3</td><td>120 seconds</td></tr><tr><td>Windows</td><td>VS2013, Update 4</td><td>121 seconds</td></tr><tr><td>Windows</td><td>VS2013, Update 4, optimizations off</td><td>137 seconds</td></tr><tr><td>Linux</td><td>g++ 4.8.1</td><td>79 seconds</td></tr><tr><td>Linux</td><td>g++ 4.9.2</td><td>76 seconds</td></tr></table> <p>I'm pretty sure that the one-second difference between VS updates is within noise, though I dread that it may be a performance regression. Turning optimizations off demonstrates that they are at least doing something. </p> <p>Under Linux, there is a noticeable improvement between the steam-runtime-targeting g++ 4.8 and my system-wide g++ 4.9; whether it's a compiler or standard library difference isn't clear; but it is certainly nice when newer compilers make old code faster. </p><p>Finally, I'm surprised that the Windows/VS version is doing so poorly compared to Debian/g++ -- my previous experience has been that cl.exe produces code that is a fair bit <em>faster</em> than either g++ or clang++. I'm left wondering if this particular code is something that cl.exe fails to optimize properly, or if the Windows stack is failing somewhere else (filesystem read performance? standard library implementation?). There could even be exotic hardware causes -- Windows and Linux are run from different [though identically-branded, purchased-at-the-same-time] SSDs -- perhaps one is slower. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-89859364378138506002015-02-21T10:31:00.000-05:002015-02-21T10:31:36.343-05:00Rainbow is a Pocket Gamer 2015 Nominee<p>My rainbow-driving game, <a href="http://tchow.com/games/rainbow">Rainbow</a> (available for <a href="https://itunes.apple.com/us/app/tchow-rainbow/id720832787">iOS</a> and <a href="https://play.google.com/store/apps/details?id=com.tchow.rainbow">Android</a> for approximately $1) has been nominated for a Pocket Gamer award in the "Most Innovative" category. </p><p>Please head over to <a href="http://www.pocketgamerawards.com">Pocket Gamer</a> to vote. It's almost certainly not going to win, but one must try, eh? </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-L5NK2Ok4Qck/VOikE26fWNI/AAAAAAAACrE/d2JnodCo5vQ/s1600/pocket-gamer.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-L5NK2Ok4Qck/VOikE26fWNI/AAAAAAAACrE/d2JnodCo5vQ/s400/pocket-gamer.png" /></a></div>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-52377910639395261112015-01-01T13:59:00.000-05:002015-01-01T13:59:03.567-05:00New Year Paraphernalia<p>Each year, my brother and I spend the new year's eve building a new album to release. Also, I've been trying to get in the habit of releasing a little interactive solstice / new year card around the same time. So here they are. </p><h1>Game</h1><p>This year's game is a quick implementation of a puzzle interaction involving moving blocks around. The opening animation explains it better than I could: </p><p style="text-align:center; background:#fee; border:1px black dashed; margin:2px 50px; padding: 5px;"><a href="http://tchow.com/art/card-w2014/card"><img border="0" src="http://3.bp.blogspot.com/-aV4tMgYCQtA/VKWYV8p2k7I/AAAAAAAACqc/GIvY405L4NA/s400/card-w2014.png" /></a><br /><a href="http://tchow.com/art/card-w2014/card">Play</a></p><h1>Album</h1><p>This year's is called "Sassy Bunny" and you can listen to it right now: </p><div style="text-align:center"><iframe width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/68622318&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe></div><p>Some highlights: Weird To Me -- a classic one-take Jimike song; Undone -- all sorts of interesting sounds in here; Intro -- really energetic track. Some lowlights: weird mixing in Great In The Future; She -- a track that is perhaps too mellow. </p><p>We are starting to accumulate a fair bit of audio gear. This year's album involved two guitars, a banjo, a Monotribe, three mics, and two different midi control devices -- a keyboard and a <a href="https://www.ableton.com/en/push/">Push</a> (run through a custom script to make it nice for use in Reason). </p><p>As always, expect Spotify links when we get around to pushing the files to our distributer. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-20862655292533226512015-01-01T13:35:00.000-05:002015-01-01T13:35:55.086-05:00Why Rainbow fails on iOS 8<p>Last week, I received a disturbing bug report from an iOS 8 user: Rainbow, it seems, wasn't properly saving any game state. So, I sat down to see what the problem was. </p><p>The culprit seems to be the helper function <code>user_data_dir</code>, which is responsible for figuring out where to store data files for the game: </p><pre><code>string user_data_dir(string const &app_name)<br /> /* ... */<br /> #elif defined(IOS)<br /> ret = "../Documents";<br /> #elif defined(ANDROID)<br /> /* ... */<br /> return ret;<br />}</code></pre><p>Hmm. A hardcoded path. That seems brittle. </p><p>Looking up user data paths and iOS 8, I came across a <a href="https://developer.apple.com/library/ios/technotes/tn2406/_index.html">tech note</a> which pretty succinctly explained the situation. Basically, the <code>Documents</code> directory is no longer a sibling of the application, so must be requested using a (ObjC) call, which I ended up dumping into a different (compiled-as-ObjC++) file: </p><pre><code>std::string documents_directory() {<br /> return [[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] path] UTF8String];<br />}</code></pre><p>And that seems to have done it. Expect a 1.5.2 version of Rainbow to appear soon. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-89501684107846565652014-11-17T22:39:00.000-05:002014-11-17T22:40:14.666-05:00Soon, You Will Fly: a Leap Motion 3D Jam game<p>Thanks to a soft deadline this morning, I've posted an <a href="http://itch.io/jam/leapmotion3djam/rate/14034">alpha build</a> (for Windows and OSX) of a weird little game I've been working on for the <a href="http://itch.io/jam/leapmotion3djam">Leap Motion 3D Jam presented by IndieCade</a>. It's called "Soon, You Will Fly", and -- perhaps unexpectedly -- it's about crawling. </p><div style="text-align:center"><iframe src="//itch.io/embed/14034" width="552" height="167" frameborder="0"></iframe></div><p>I'm still working on a few things. Among them: tentacles, a heart/eye, the touch of darkness, and more sound design. Oh, and a way to quit without resorting to ALT-F4. </p><p>Anyway, please do check it out and let me know what you think. At present, I'm thinking that this probably doesn't extend beyond a simple jam game; but feedback can change that. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-24727532436792847752014-09-04T22:17:00.000-04:002014-09-04T22:17:20.697-04:00Fragments: a Ludum Dare Jam Game<p>A few weeks ago, I worked with my friend Aaron Vonderhaar on a bold experiment: to develop a single-page html game framework and then build a game in it for <a href="http://www.ludumdare.com/">Ludum Dare</a>. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-KEKsdBOJnbo/VAkbA3Ub5CI/AAAAAAAACpM/Wp8v2-96p5s/s1600/frag-ss-00.png" /></div><p>The result is <a href="http://ixchow.github.io/arrange/">Fragments</a>[<a href="http://www.ludumdare.com/compo/ludum-dare-30/?action=preview&uid=18837">Ludum Dare Page</a>] [<a href="https://github.com/ixchow/arrange">Source Code</a>]. It's a put-together puzzle in isometric 3d, telling a somewhat fragmented story of mangled memories. </p><p>I'm not entirely happy with how the game came out, but as my first Ludum Dare Jam (as opposed to compo) experience, it was a decent one. It was fun working with Aaron on a project, and I think we did some interesting things in the game framework -- though it wasn't <em>nearly</em> complete enough going into the competition. </p><p>Two interesting points of trivia about <i>Fragments</i>: </p><ul><li>There is no lighting in the game. Everything is baked to vertex colors in <a href="http://www.blender.org/">Blender</a> during export. This is a trick I also used in <a href="http://tchow.com/games/rainbow/">Rainbow</a> for the landscape.</li><li>For some reason, 30% of the CPU time in the game is used by 4x4 matrix multiplies. We probably should have been looking at profiling data earlier. It appears that the construction of <a href="https://github.com/ixchow/arrange/blob/master/engine/Mat4.js">Mat4</a>'s is very expensive. </li></ul>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-75406908620964067002014-02-06T15:56:00.002-05:002014-02-06T15:56:37.606-05:00Seven Skills of Highly Effective Rainbow Players<p>It has been a long time in coming, but I finally created a promotional video for <a href="http://tchow.com/games/rainbow/">Rainbow</a>. Promotional and educational, I should say. </p><p>Take a gander: </p><div style="text-align:center"><iframe width="560" height="315" src="//www.youtube.com/embed/TsRrlKom4_Y?rel=0" frameborder="0" allowfullscreen></iframe></div>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-68665086918926419892014-01-14T13:05:00.000-05:002014-01-14T13:05:53.951-05:00Iterating on Promo Art for Rainbow<p><a href="http://tchow.com/games/rainbow/">Rainbow</a> for iOS (and for Android!) will be out tomorrow, and as part of the assets for the Google Play store, I needed to design a large (1024x500) promotional image for the game. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/--51QWXQnzms/UtV3nqPpWWI/AAAAAAAACdI/GGZqDd5FB-U/s1600/v4.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/--51QWXQnzms/UtV3nqPpWWI/AAAAAAAACdI/GGZqDd5FB-U/s400/v4.png" /></a></div><p>As you can see above, I arrived at an pretty good image. I think it captures the essence of Rainbow's art style and gameplay, while striking a balance between cleanliness and boredom. </p><p>Arriving at this image required a few iterations. My first mockups had a hand-drawn rainbow that just didn't seem lively enough: </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-I8id28mllIQ/UtV4Kd-WJYI/AAAAAAAACdQ/NiSkW7sNtWM/s1600/v1.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-I8id28mllIQ/UtV4Kd-WJYI/AAAAAAAACdQ/NiSkW7sNtWM/s320/v1.png" /></a><a href="http://2.bp.blogspot.com/-hiobMLuo5uE/UtV4KmNKpQI/AAAAAAAACdU/3RzoJgQxq60/s1600/v1-alt.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-hiobMLuo5uE/UtV4KmNKpQI/AAAAAAAACdU/3RzoJgQxq60/s320/v1-alt.png" /></a></div><p>I tried patching in some spirals, but they still didn't look right to me. Perhaps this is because I'm over-familiar with the way cubic splines look (and/or the way rainbows actually move in the game): </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-uLKhQoEEKhY/UtV4qCA4A1I/AAAAAAAACdg/fGffVs_XEao/s1600/v2.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-uLKhQoEEKhY/UtV4qCA4A1I/AAAAAAAACdg/fGffVs_XEao/s400/v2.png" /></a></div><p>So I ended up hacking in a special game mode that uses a white background and hides the level while taking screenshots; and repeatedly played through a simple (splitter-only) level to come up with some rainbow patterns. This turns out to be somewhat difficult. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-6fzVN2XSosU/UtV7FRxmzyI/AAAAAAAACdo/POaj9EmmRMw/s1600/v3.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-6fzVN2XSosU/UtV7FRxmzyI/AAAAAAAACdo/POaj9EmmRMw/s400/v3.png" /></a></div><p>This was good as a first cut, but too busy. After trimming a few of the characters from the bottom of the image, and playing through my empty level several more times, I arrived at the final version: </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/--51QWXQnzms/UtV3nqPpWWI/AAAAAAAACdM/pK_ORPYFTS0/s1600/v4.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/--51QWXQnzms/UtV3nqPpWWI/AAAAAAAACdM/pK_ORPYFTS0/s400/v4.png" /></a></div><p>I also needed a smaller version of the image with a slightly different aspect ratio (180x120). For this I re-arranged the TCHOW logo to above the word "Rainbow" and strengthened the halo to make the letters more readable: </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-h5TCDRJy1NQ/UtV7pQdccFI/AAAAAAAACd8/fXVklYs7NLg/s1600/v5.png" /></div><p>The final promo and small promo images -- along with high-res versions of other game assets -- can be obtained from the <a href="http://tchow.com/games/rainbow/press/#logos">Rainbow Press Kit</a>. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-56746147675090818972014-01-10T14:15:00.001-05:002014-01-10T14:15:14.705-05:00Rainbow for iOS out on January 15th<p>It's been a while, but Rainbow is finally ready to go on sale in the iOS App store. The game will be out on the 15th of this month, and will sell for $2. </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-SCai66QOxS4/UtBGM-wgtgI/AAAAAAAACag/2TPH8VoFOVE/s1600/Rainbow-In-Game.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-SCai66QOxS4/UtBGM-wgtgI/AAAAAAAACag/2TPH8VoFOVE/s400/Rainbow-In-Game.png" /></a></div><p>More information about Rainbow can be found on the game's <a href="http://tchow.com/games/rainbow/">web page</a> and <a href="http://tchow.com/games/rainbow/press/">press kit</a>. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-29502134612126135792013-11-13T13:03:00.002-05:002013-11-13T13:03:50.543-05:00Math: What is the right Aspect Ratio?<p>In the shower the other day, I thought up an interesting question: what is the right <a href="http://en.wikipedia.org/wiki/Aspect_ratio_(image)">aspect ratio</a> to work in? (With, of course, the immediate follow-up question: what does "right" mean in this context?) In this post, I'll attempt to answer both questions with some simple math. </p><h2>Setup</h2><p>I've been doing some pre-production work on a storybook game for iOS devices. The game will likely be composed of full-screen scenes with hand-drawn background plates. I don't want to have require new background plates for every resolution (much less aspect ratio), so the plan is to create one background and fit it to the screen. </p> <div style="text-align:center"><a href="http://1.bp.blogspot.com/-pS0JpG7Ds7I/UoOcV6-oaxI/AAAAAAAACMw/tMJsb3ugUB4/s1600/h_crop.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-pS0JpG7Ds7I/UoOcV6-oaxI/AAAAAAAACMw/tMJsb3ugUB4/s200/h_crop.png" /></a><a href="http://2.bp.blogspot.com/-c_CjUPhhLwk/UoOcV-jNjuI/AAAAAAAACM0/qleBRjw9szo/s1600/v_crop.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-c_CjUPhhLwk/UoOcV-jNjuI/AAAAAAAACM0/qleBRjw9szo/s200/v_crop.png" /></a></div><p>So, depending on the screen aspect ratio (in this case: 4:3 on the left, 16:9 on the right), some of the image will be cropped, either off the sides or off the top and bottom. </p> <h2>Minimizing Waste</h2><p>Since I'm not of a mind to have something drawn that isn't needed, one possible definition of "right" aspect ratio is the one that minimizes wasted area in the background image. So how much area is wasted? </p><p>Well, denoting the aspect ratio of the screen <code>s</code> and the aspect ratio of the background image <code>b</code>, and -- without loss of generality -- assuming the screen height is <code>1</code>, it is easy to draw a picture of the situation: </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-gPKTm37PEic/UoOgR7SfUtI/AAAAAAAACNE/N7ISHti586o/s1600/variables.png" /></div><p>So, if the background is wider than the screen, the percentage of the background image wasted is <code>(b-s) / b</code>. Similarly, when the background is narrower, the waste is <code>(1/b-s) / (1/b)</code>. </p><p></p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-quPfzU_lbDQ/UoOregtk0fI/AAAAAAAACNU/ZLIF5cEPWww/s1600/just4:3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-quPfzU_lbDQ/UoOregtk0fI/AAAAAAAACNU/ZLIF5cEPWww/s320/just4:3.png" /></a></div><p>As expected, on a 4:3 screen a background image of aspect ratio 4:3 wastes the least. </p><p>Of course, on iOS one needs to worry about three aspect ratios: 4:3 [iPad], 3:2 [iPhone <= 4], and 71:40 [iPhone >= 5]. (In case you are wondering, 71:40 is 'nearly 16:9'.): </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-LXVHPCKS0rY/UoOsprABJcI/AAAAAAAACNk/b5hrtx4qhms/s1600/all.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-LXVHPCKS0rY/UoOsprABJcI/AAAAAAAACNk/b5hrtx4qhms/s320/all.png" /></a></div><p><em>NOTE:</em> I'm only considering landscape aspect ratios because that's the target for this game. </p><p>Assuming one wants to give equal weight to background waste on each device, the proper aspect ratio of the background image should minimize the sum of these three curves. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-VUSHfqKhWj4/UoOtQcea_WI/AAAAAAAACNs/tuQWonMvM9k/s1600/sum.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-VUSHfqKhWj4/UoOtQcea_WI/AAAAAAAACNs/tuQWonMvM9k/s320/sum.png" /></a></div><p>This minimization happens at the 3:2 aspect ratio. Indeed, my intuition is that with equally-weighted devices the minimum-waste aspect ratio will always be the median aspect ratio. </p> <h2>Maximizing Excitement</h2><p>In the previous section, I counted areas of the background for each time they were cropped -- that is, background that didn't show at 4:3 and at 3:2 was counted as being twice as bad as background that was only cropped at 3:2. Perhaps, instead of obsessing over these lost pixels, one should instead maximize the percentage of the background that is cropped by no device (i.e. the part of the background every screen sees). </p><p>What is this percentage? Consider a background of size <code>b</code>x<code>1</code> to be shown on screens of aspect <code>s1</code>, ..., <code>sN</code>. The width of the visible-on-all-screens region is <code>w = min(b, s1, ..., sN)</code>, because the background will be cropped after its aspect exceeds the smallest screen aspect. The height of the visible region is <code>h = min(1, b / s1, ..., b / sN)</code>, because of cropping on the top and bottom of edge of the background when it is scaled to the widest aspect ratio. (More intuition: consider scaling the visible region to [horizontally] fit a screen of size <code>s</code>x<code>1</code>. The scale factor is <code>s / b</code>, so it must be the case that <code>h * s / b <= 1</code>; thus <code>h <= b / s</code>.) </p><p>Putting these figures together gives percentage <code>100 * min(b, s1, ..., sN) * min(1, b / s1, ..., b / sN) / (b * 1)</code>. Interestingly, this means that maximizing visible area only depends on the narrowest and widest aspect ratio under consideration: </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-adc79AnI0Hk/UoO7CcV4mmI/AAAAAAAACOo/c5XlQAJwMVU/s1600/visible_all.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-adc79AnI0Hk/UoO7CcV4mmI/AAAAAAAACOo/c5XlQAJwMVU/s320/visible_all.png" /></a></div><p>The unfortunate news is that with aspect ratios of 4:3 and 71:40 in the mix there isn't any background size that doesn't end up with about 25% of its area not visible on all screens. The fortunate news is that the best aspect ratio in terms of waste (3:2) is within this 75%-used plateau. </p> <h2>Going Further</h2><p>In this article I didn't talk at all about foreground content (which must be scaled to fit within each aspect ratio), and only explored two objective functions. Other interesting objective functions might include one weighted for all <a href="http://browsersize.googlelabs.com/">browser sizes</a>, or one that is concerned with fairness (forcing all screens to lose about the same area of the background). </p><p>If you have other ideas, feel free to leave a comment or send an <a href="mailto:ix@tchow.com">e-mail</a>. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-25372521734499377832013-11-06T14:22:00.000-05:002013-11-06T14:22:01.729-05:00Rainbow Update: More Music<p>I am pleased to report that the iOS version of <a href="http://tchow.com/games/rainbow/">Rainbow</a> is proceeding well. In fact, a 1.0 version has already been accepted for app store sale (though -- owning to some gameplay changes -- I will probably not release it). </p><p>So, what have I been working on? Well, other than finding a real job, tweaking and adjusting Rainbow to be an even better game. Part of that is doing things like adding incidental music to cutscenes -- and that's what this post is about. </p><h2>The Music</h2><p>The most recent two tracks I added to Rainbow were an opening and closing theme for the villain (and player's persona), who I will simply call "D.D." herein. </p> <p>The opening theme is meant to be sinister but energetic, as befits a villain whose goal is to bring color and happiness into the lives of a drab people: </p> <iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/118868670"></iframe> <p>The closing theme is meant to be similar to the opening theme but more mellow, because D.D. is now tired from the effort of playing through the game: </p> <iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/118868161"></iframe> <p>One of the things that I think works really well in both of these tracks is the drums. The main drums are from Reason's factory sound library, but are bit-crushed via a Scream4's "digital" method: </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-9ZSS6FZPfhw/UnqTo9h9caI/AAAAAAAACMI/jpJ3bp2_Mr4/s1600/drums.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-9ZSS6FZPfhw/UnqTo9h9caI/AAAAAAAACMI/jpJ3bp2_Mr4/s320/drums.png" /></a></div><p>I also automate the 'Rate' parameter of the Scream4 in one of the tracks to get some interesting variation into the drums. It's certainly a rough sound, but it's one that I quite enjoyed using in <a href="https://soundcloud.com/tchow/bit-crushed-zombies-of-monkey">an earlier track</a>. </p><p>The parallel channel through the reverb and compressor is generally mixed very low, but it does provide some interesting texture. (The LFO is being used to sweep the resolution on the Scream4 in this channel, which adds more rhythm to the texture.) </p><p>In addition to the main drums, I use a lone synth kick, without any fancy effects, in parts of the track. This kick is used as an sidechain input on the lower pad, in order to make the pad duck the kick (and thus make the kick seem to hit harder): </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-iQQ9_Widvuk/UnqU5PHYA-I/AAAAAAAACMQ/Hn1g_4CvYdo/s1600/drums2.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-iQQ9_Widvuk/UnqU5PHYA-I/AAAAAAAACMQ/Hn1g_4CvYdo/s320/drums2.png" /></a></div><p>I doubt Rainbow will be winning any awards for cutscene music design, but these snippets certainly seem better than letting the menu theme continue to play. </p> Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-69279364411563827942013-10-10T11:41:00.000-04:002013-10-11T00:57:29.548-04:00Rktcr Limited Edition (Video)<p>With just about 12 hours left in the <a href="https://indiegamestand.com/?saleId=112">Indie Game Stand</a> sale for <a href="http://tchow.com/games/rktcr/">Rktcr</a>, I decided to make the following video to give folks a better look at the Rktcr Limited Physical Edition, one of which has now been claimed by the highest contributor in the aforementioned sale. </p> <div style="text-align:center"><iframe width="560" height="315" src="//www.youtube.com/embed/HQBIVsiUB8k?rel=0" frameborder="0" allowfullscreen></iframe></div> <p>So if you think this looks cool, start figuring out how to convince me to part with the other copy. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-5890450600500597432013-10-04T13:04:00.001-04:002013-10-11T00:55:30.352-04:00Rktcr's Limited Edition<p>From October 7th-10th, <a href="http://tchow.com/games/rktcr">Rktcr</a> was on pay-what-you-want sale at <a href="https://indiegamestand.com/?saleId=112">Indie Game Stand</a>, with 10% of proceeds supporting the <a href="http://eff.org">EFF</a>. Paying more than average would have netted you an exclusive level pack and a custom digital wallpaper. But that's not what this post is about. </p><p>Paying the <b>most</b> would have gotten you one of the only two limited edition physical copies of the game. And these things are amazing. And that is what this post is about. </p> <div style="text-align:center"><a href="http://4.bp.blogspot.com/-hZE-DiEeaOc/Uk7nWFsXY1I/AAAAAAAACHw/ENTKAxeG4mA/s1600/rktcr-le-open.jpg" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-hZE-DiEeaOc/Uk7nWFsXY1I/AAAAAAAACHw/ENTKAxeG4mA/s500/rktcr-le-open.jpg" /></a></div> <p>Each one is an obsessively-crafted testament to my deep love for Rktcr, and feature (from outside to inside): </p> <div style="text-align:center"><a href="http://1.bp.blogspot.com/-qUCl-RzjaZE/Uk7u6v3X8TI/AAAAAAAACIs/RW2hpYcpqiY/s1600/rktcr-le-band.jpg" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-qUCl-RzjaZE/Uk7u6v3X8TI/AAAAAAAACIs/RW2hpYcpqiY/s500/rktcr-le-band.jpg" /></a></div> <div style="text-align:center;margin-top:10px"><a href="http://3.bp.blogspot.com/--WCJuTwLsnU/Uk7u7RB704I/AAAAAAAACI0/i0ACwza1bKw/s1600/rktcr-le-band-back.jpg" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/--WCJuTwLsnU/Uk7u7RB704I/AAAAAAAACI0/i0ACwza1bKw/s200/rktcr-le-band-back.jpg" /></a></div><p>A paper "Rktcr"-logo band, made from five interleaved sheets, hand-cut and painstakingly assembled.</p> <div style="text-align:center"><a href="http://2.bp.blogspot.com/-Jg4cRDvoUCc/Uk7pW1PKbVI/AAAAAAAACH8/HaKvnLG60ew/s1600/rktcr-le-pair.jpg" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-Jg4cRDvoUCc/Uk7pW1PKbVI/AAAAAAAACH8/HaKvnLG60ew/s400/rktcr-le-pair.jpg" /></a></div><p>A Rktcr sprite print box. Each of the four patterns used on these two boxes and their lids are unique and will never appear elsewhere.</p> <div style="text-align:center"><a href="http://3.bp.blogspot.com/-7WFMrmsEySo/Uk7pxsOk01I/AAAAAAAACIE/Mt3yWTv34T8/s1600/rktcr-le-velvet.jpg" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-7WFMrmsEySo/Uk7pxsOk01I/AAAAAAAACIE/Mt3yWTv34T8/s400/rktcr-le-velvet.jpg" /></a></div><p>A hand-made velvet/foam cushion to showcase...</p> <div style="text-align:center"><a href="http://2.bp.blogspot.com/-_xeZ72v3Y_M/Uk7uhVT7zOI/AAAAAAAACIk/r1RLpMC0h84/s1600/rktcr-le-leaf.jpg" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-_xeZ72v3Y_M/Uk7uhVT7zOI/AAAAAAAACIk/r1RLpMC0h84/s320/rktcr-le-leaf.jpg" /></a></div> <p>...a USB drive filled with Rktcr v3.1 and covered in 23K gold leaf, ...</p> <div style="text-align:center"><a href="http://2.bp.blogspot.com/-vlf2LXSoq0Y/Uk7sqm8VFWI/AAAAAAAACIQ/8L3xfazqXqs/s1600/rktcr-le-mac.jpg" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-vlf2LXSoq0Y/Uk7sqm8VFWI/AAAAAAAACIQ/8L3xfazqXqs/s250/rktcr-le-mac.jpg" /></a> <a href="http://4.bp.blogspot.com/-2ajsX4IkQUg/Uk7ssS12zLI/AAAAAAAACIY/mxrwO2dyv9Q/s1600/rktcr-le-pc.jpg" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-2ajsX4IkQUg/Uk7ssS12zLI/AAAAAAAACIY/mxrwO2dyv9Q/s250/rktcr-le-pc.jpg" /></a></div><p>...with a silver-plated chain tassel.</p> <div style="text-align:center"><a href="http://4.bp.blogspot.com/-cdgyUMgC2Yw/Uk7zGWAq4DI/AAAAAAAACJA/rM1cpgVvz2g/s1600/rktcr-le-boxes.jpg" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-cdgyUMgC2Yw/Uk7zGWAq4DI/AAAAAAAACJA/rM1cpgVvz2g/s500/rktcr-le-boxes.jpg" /></a></div> <p>These two limited edition copies are truly amazing things. They, in as non-creepy a sense as possible, reify my deep love for Rktcr, my desire to see it perfected, and my joy at finishing the game. The whole assemblage has a nice weight in the hand, and the drive and chain feel luxurious as you manipulate them. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-64822199258357882942013-10-01T11:58:00.000-04:002013-10-01T11:58:35.951-04:00Making Rktcr Levels: Bursts<p>I'm trying to spend most of my time as of late getting an iOS beta for <a href="http://tchow.com/games/rainbow/">Rainbow</a> out, so this <a href="http://tchow.com/games/rktcr/">Rktcr</a> tutorial will be a brief one. </p><p>In this tutorial, I will show you how to make bursts -- those little exploding circles that can give the player's vehicle a shove in the right (or wrong) direction. </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-Vx0eGCUTgwY/UkrwX97upVI/AAAAAAAACGw/RT4_7lPw8z0/s1600/burst-a.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-Vx0eGCUTgwY/UkrwX97upVI/AAAAAAAACGw/RT4_7lPw8z0/s200/burst-a.png" /></a><a href="http://2.bp.blogspot.com/-KfP0XOALJ7Q/UkrwX_xw5LI/AAAAAAAACHA/8eA0e-HGq8I/s1600/burst-b.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-KfP0XOALJ7Q/UkrwX_xw5LI/AAAAAAAACHA/8eA0e-HGq8I/s200/burst-b.png" /></a><a href="http://2.bp.blogspot.com/-wZfBxNmuvsE/UkrwX5_h5gI/AAAAAAAACG0/mSV9ns-ob00/s1600/burst-c.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-wZfBxNmuvsE/UkrwX5_h5gI/AAAAAAAACG0/mSV9ns-ob00/s200/burst-c.png" /></a></div><p>I will be assuming familiarity with <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">the basics</a>, but nothing more. (Well, other than a <a href="http://tchow.com/games/rktcr/#buy">full version</a> of Rktcr.) </p><h2>Bursts</h2><p>Bursts are actually just gems with the special name. So, to make one, first create a gem (<kbd>space</kbd>, <kbd>g</kbd><kbd>e</kbd><kbd>m</kbd>, <kbd>enter</kbd>), then edit its properties (<kbd>tab</kbd>), and set the name to <code>burst</code>. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-2qmYGio3Gyw/UkrwsUKTs9I/AAAAAAAACHI/OHU9_vFgg3E/s1600/name.png" /></div><p>You can still use the <code>front_collide</code> and <code>back_collide</code> properties, like <a href="http://news.tchow.com/2013/09/making-rktcr-levels-disruptables.html">on gems</a>, to change which wheel(s) will trigger the burst. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-zv7mzSNGpb4/Ukrw2NsVh1I/AAAAAAAACHQ/2BbediEXwJQ/s1600/collide.png" /></div><p>And that's it! A short tutorial, to be sure, but the upcoming one about style layers will be quite a bit longer. (And, after that, there's only claims and I'll have taught you all there is to know about Rktcr level editing.) </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-61303572360205144232013-09-24T11:31:00.000-04:002013-10-01T12:00:51.405-04:00Making Rktcr Levels: Disruptable Platforms and Gems<p>In this <a href="http://tchow.com/games/rktcr/">Rktcr</a> editing tutorial, I'll talk about how to create disruptable platforms and gems. These are platforms and gems that only one of the vehicle's wheels collide with. This tutorial assumes knowledge of the <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">editor basics</a>. </p><p>If you <a href="http://tchow.com/games/rktcr/#buy">own</a> the full version of Rktcr (and, really, <a href="http://tchow.com/games/rktcr/#buy">you should</a>), you can grab <a href="http://tchow.com/games/rktcr/rktcr-leveltut-disrupt.zip">this level pack</a> to follow along. </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-oFEqtc5l3uk/UkGmculAtGI/AAAAAAAABvM/RkrwrZUuZRQ/s1600/plan.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-oFEqtc5l3uk/UkGmculAtGI/AAAAAAAABvM/RkrwrZUuZRQ/s500/plan.png" /></a></div><p>In this tutorial, we'll make a level where the player needs to navigate out of the a starting box by letting the front wheel fall through one segment and the back fall through another. After this, the player will need to pick up the final gem with the appropriate wheel (lest it be knocked into the abyss). </p><h2>Disruptable Platforms</h2><p>First, we'll make the two short segments in the bottom of the starting area disruptable by going into property edit mode (select, <kbd>shift</kbd>-<kbd>tab</kbd>), selecting <code>collide</code> (<kbd>up</kbd>/<kbd>down</kbd>, then <kbd>enter</kbd>), and changing the value to <code>1</code>/<code>2</code> for the left/right segment (<kbd>delete</kbd>, <kbd>1</kbd>/<kbd>2</kbd>, <kbd>enter</kbd>). </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-ACQMJZjeA9A/UkGpw-hfxVI/AAAAAAAABvY/AVOUQgp3nMg/s320/left.png" /><img border="0" src="http://1.bp.blogspot.com/-URQU5Iylqms/UkGpw_9b4QI/AAAAAAAABvc/8tnufZGnZ-4/s320/right.png" /></div><p>The polygons will now be highlighted in white/gray, indicating that the front/back wheel (only) will collide with them. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-UmzFsr7T3Zo/UkGql2hfzTI/AAAAAAAABvo/uO4-Ix8V3mY/s1600/frontback.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-UmzFsr7T3Zo/UkGql2hfzTI/AAAAAAAABvo/uO4-Ix8V3mY/s400/frontback.png" /></a></div><p>Of course, it never hurts to actually check by playtesting the level (select start portal, then press <kbd>enter</kbd>). </p><h2>Disruptable Gems</h2><p>Making the gem collide (instead of be picked up by) the front wheel is a similar procedure. Select the gem, drop into edit mode (<kbd>tab</kbd>) and set the property <code>front_collide</code> to <code>1</code>: </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-6iBhtm0iTAI/UkGsHnwX6xI/AAAAAAAABv0/eaJLW0ebA2Y/s320/gem.png" /></div><p>The gem will be surrounded with a white band to indicate that the front wheel collides with it. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-0x67J7TbuV0/UkGsMUfsoBI/AAAAAAAABv8/VtdRDQ6gPzM/s320/gem-back.png" /><img border="0" src="http://2.bp.blogspot.com/-9EY-LbP5zQw/UkGsMWMFarI/AAAAAAAABwA/bZ_0o3B7sio/s320/gem-front.png" /></div><p>As before, you can always confirm that things are working as you expect by playtesting. </p><h2>Conclusion</h2><p>In today's rather short tutorial, I showed you how to make disruptable platforms by setting the <code>collide</code> property on level geometry, and how to make disruptable gems by setting that <code>front_collide</code> and <code>back_collide</code> properties on gems. It is worth noting that -- though we did not do so in this tutorial -- you can also change the <code>collide</code> property on <a href="http://news.tchow.com/2013/09/making-rktcr-levels-dynamics.html">dynamics</a>. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-EIBO6ql8cOA/UkGuwPdnbUI/AAAAAAAABwQ/Lvi9Bc2ZQGQ/s1600/final.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-EIBO6ql8cOA/UkGuwPdnbUI/AAAAAAAABwQ/Lvi9Bc2ZQGQ/s500/final.png" /></a></div><p>Disruptable platforms and gems can lead to situations where players need to carefully consider the vehicle's orientation. They can add challenge to maze-like levels and also allow for tricky momentum-conservation strategies (like letting the wheel that does not collide spin around the one that does). </p><h2>Next Steps</h2><p>I've covered nearly all of the features of the Rktcr editor. The only tutorial subjects that remain are <a href="http://news.tchow.com/2013/10/making-rktcr-levels-bursts.html">bursts</a>; style layers; and claims. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-5861873052893309852013-09-17T15:37:00.002-04:002013-10-01T12:00:30.616-04:00Making Rktcr Levels: Dynamics and Constraints<p>In this <a href="http://tchow.com/games/rktcr/">Rktcr</a> level creation tutorial, I will describe how to add dynamic (i.e. physically-simulated) geometry to levels, and how to add constraints between these dynamic bodies. This tutorial builds on ideas introduced in the <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">basics</a> and <a href="http://news.tchow.com/2013/09/making-rktcr-levels-geometry-types.html">geometry</a> tutorials. </p><p>And, as before, you'll need the latest <a href="http://tchow.com/games/rktcr/#buy">full version</a> of Rktcr (v3.1 as of this writing). </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-gtufazuy4wg/UjiGtXNdfoI/AAAAAAAABs0/ael7YvWKtTg/s1600/plan.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-gtufazuy4wg/UjiGtXNdfoI/AAAAAAAABs0/ael7YvWKtTg/s500/plan.png" /></a></div><p>In this tutorial, I'll start with some existing static geometry, and make some of it dynamic. Above, you can see the plan I'll be following. </p><p>If you'd like to follow along, you can download a zip file containing this level (along with the finished version) <a href="http://tchow.com/games/rktcr/rktcr-leveltut-dynamics.zip">here</a>. Place the files in your ".rktcr/e_levels" folder, start Rktcr in edit mode, and load <code>tut-dynamics</code> with <kbd>f4</kbd>. </p><h2>Making Dynamics</h2><p>In Rktcr, all dynamic bodies are created from static geometry, much in the same way <a href="http://news.tchow.com/2013/09/making-rktcr-levels-geometry-types.html#smooth">smoothed polygons</a> are created from regular polygons. </p><div style="text-align:center"><img border="0" src="http://4.bp.blogspot.com/-g1rfX2c9dBY/UjiKN3fAxvI/AAAAAAAABtA/fsXQvIcb_Hc/s1600/dynamic.gif" /></div><p>Select the static geometry you'd like to make dynamic with right-click, press <kbd>space</kbd> to open the creation prompt, type <kbd>d</kbd><kbd>y</kbd><kbd>n</kbd><kbd>a</kbd><kbd>m</kbd><kbd>i</kbd><kbd>c</kbd> (or <kbd>d</kbd><kbd>tab</kbd>, if you're feeling lazy), and press <kbd>enter</kbd>. </p><p>You can make a dynamic body static again by selecting it (right click) and pressing <kbd>x</kbd>. (This deletes the "dynamic" modifier.) </p> <h2>Dynamics Parameters</h2><p>Dynamics have two types of edit mode: geometry (<kbd>tab</kbd>), and parameter (<kbd>shift</kbd>-<kbd>tab</kbd>). Geometry edit mode does what you'd expect -- edits the geometry underlying the dynamic. Parameter edit mode allows you to change some physical (and physics-effecting) parameters: </p> <ul><li><b>source_tag</b> shouldn't be changed.</li><li><b>seed</b> is the seed for the (somewhat randomized) convex decomposition algorithm. If you don't like how the dynamic is being split into red and green regions, change this.</li><li><b>gravity</b> is the direction of gravity effecting the block (0-7 are fixed, 8 is "down relative to the current view").</li><li><b>density</b> is what it sounds like. If the object seems too heavy, use something lower.</li><li><b>moment_factor</b> scales the moment of inertia. Increasing/decreasing will make the object spin less/more easily.</li><li><b>rel_pos</b> is a starting offset for the object as (x,y,theta). It don't recommend using it.</li></ul> <div style="background:#fcc; padding:10px; margin:20px 0"><h2 style="color:#800; background:#fff;margin:0 -10px;padding:0 0 0 20px">Warning</h2><p>When working when dynamics, save often! Sometimes, the convex decomposition produced by Rktcr's code can contain degenerate polygons, which -- in turn -- will make Box2D (which Rktcr uses for simulation) <code>assert()</code> when you attempt to test a level. </p><p>There will be a fix for this in the next version of Rktcr. Until then, <em style="background:#fff">save before you test</em>. (The -- admittedly cumbersome -- work-around is to change the <code>seed</code> value used on the problematic dynamic until you find one where the editor doesn't exit upon running the level.) </p></div> <h2>Testing</h2><p>This is what the level looks like after creating all the required dynamics: </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-baDY5IeNKNA/UjiRinUHwiI/AAAAAAAABtQ/YNnUQw4Y7r8/s1600/all_dynamic.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-baDY5IeNKNA/UjiRinUHwiI/AAAAAAAABtQ/YNnUQw4Y7r8/s500/all_dynamic.png" /></a></div><p>At this point -- <b>be sure to save!</b> -- you can press <kbd>enter</kbd> to go into physics test mode. (If you end up in play test mode, it's because a portal side was selected.) In physics test mode time runs inexorably forward, and you can grab and pull on objects using the mouse. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-bJvT41GZjgg/UjiVvvX6q1I/AAAAAAAABtc/3TlVgRXciio/s1600/pull.gif" /></div><p>Physics test mode will be useful as we create our various constraints. </p> <h2>Constraints</h2><p>Plain dynamics bodies are fine for creating stacks and tippy platforms, but for the sort of stunts we have planned for this level, we need some physics constraints. Physics constraints are created in the Rktcr editor by pressing <kbd>c</kbd>. This creates a constraint between the current dynamic selected and either the previous two dynamic selected or (if the previous selection wasn't a different dynamic) the world. </p><p>Another way to say that is: to constrain two dynamics to each-other, right click on them in turn and then press <kbd>c</kbd>; to constrain a dynamic to the world, right click on it twice and press <kbd>c</kbd>: </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-WvoOAU-A4vs/Ujiec6dB9NI/AAAAAAAABt0/wnwGdWi4Z34/s1600/rope.gif" /></div><p>Once a constraint has been created, its endpoints may be moved by pressing <kbd>g</kbd> while the constraint is selected: </p><div style="text-align:center"><img border="0" src="http://4.bp.blogspot.com/-N6HrnwEkQvw/Ujif6N3noVI/AAAAAAAABuA/Mxtdt4FCfJM/s1600/rope-move.gif" /></div><p>Pressing <kbd>tab</kbd> while a constraint is selected allows you to edit its type: </p><div style="text-align:center"><img border="0" src="http://4.bp.blogspot.com/-edNDtaM1bg0/Ujigva6AF2I/AAAAAAAABuI/wYFO0Uj3vC4/s1600/rope-params.png" /></div><p>For the hanging circles in the level, we want the constraint type <code>rope</code>, which prevents the constraint points from getting further apart (but does allow them to get closer). </p><h2>Adding Ropes</h2><p>Let's finish up the rope constraints. Keep in mind that <kbd>x</kbd> can be used to delete constraints, and make sure to set the constraint type to <code>rope</code> (using edit mode -- <kbd>tab</kbd>). Also, I find that using the size-1 grid (<kbd>1</kbd>) and holding <kbd>shift</kbd> (snap to grid), helps to keep things aligned when moving constraint endpoints. </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-V4p0p0W1oak/UjiktrfC_AI/AAAAAAAABuU/ZpHkfmRMb7Q/s1600/all_ropes.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-V4p0p0W1oak/UjiktrfC_AI/AAAAAAAABuU/ZpHkfmRMb7Q/s400/all_ropes.png" /></a></div><p>Note that the red/blue color of the lines connecting a constraint to its adjacent dynamics depends on the order in which they were selected, and isn't important to the actual simulation (so if yours don't match mine, don't worry). </p><p>At this point (and <b>after saving</b>), you can drop into test mode with <kbd>enter</kbd> and make sure everything moves how you want it to (e.g. try dragging the circles with your mouse to get a feel for the rope constraint). </p><h2>Other Constraints</h2><p>The first stunt in the level uses rod constraints. Create these as before, but make sure there is no previously selected dynamic by right-clicking on the c-shaped piece twice before pressing <kbd>c</kbd>. If you do this properly, one end of the constraint (the one connected to the world) will show as an x instead of a box. Also, make sure to set their type to <code>rod</code> in edit mode (<kbd>tab</kbd>). </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-inJcq9Hccow/UjimrmOwJVI/AAAAAAAABug/1beWG6TIleY/s1600/rods.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-inJcq9Hccow/UjimrmOwJVI/AAAAAAAABug/1beWG6TIleY/s320/rods.png" /></a></div><p>I slightly offset the bottom sides of the rod constraints because if I let them start vertical the c-shape would fall before the vehicle entered it. (This is one reason test mode is super-useful when working with dynamics.) </p><p>Finally, connect the ramp to the background with a pin constraint, so it will pivot up as the vehicle drives under it and then fall back into place. (Note that pin constraints are actually placed at the average of the two endpoints.) </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-qcO9EkXZA64/Ujinn8qzssI/AAAAAAAABuo/gQzdqeQ-wIw/s1600/pin.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-qcO9EkXZA64/Ujinn8qzssI/AAAAAAAABuo/gQzdqeQ-wIw/s280/pin.png" /></a></div><p>The constraint's type should be <code>pin</code> by default, but it doesn't hurt to hit <kbd>tab</kbd> and check. </p><h2>Finishing Up</h2><p>All the constraints are now in place: </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-5gwiEZ2Kt5k/UjiotvefiZI/AAAAAAAABuw/H3pmwnHNonU/s1600/all_constraints.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-5gwiEZ2Kt5k/UjiotvefiZI/AAAAAAAABuw/H3pmwnHNonU/s500/all_constraints.png" /></a></div><p>Generally, it's good to playtest levels as you go along, but I elided that for the sake of this tutorial. So, the question becomes: is this a winnable level? </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-NEXXHLh9L6k/UjirzKzs7UI/AAAAAAAABu8/bQQxOOrTEH8/s1600/finished.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-NEXXHLh9L6k/UjirzKzs7UI/AAAAAAAABu8/bQQxOOrTEH8/s500/finished.png" /></a></div><p>Well, the last part is quite tricky (removing the circles might be a good idea), but, yeah, it is possible. </p><h2>Next Steps</h2><p>Dynamics are one way to add excitement (and chaos) to a level, but certainly not the only way. In upcoming tutorials, I'll talk about other methods, including working with <a href="http://news.tchow.com/2013/09/making-rktcr-levels-disruptables.html">disruptable platforms and gems</a>; and <a href="http://news.tchow.com/2013/10/making-rktcr-levels-bursts.html">adding bursts</a>. I'll also go into making your level prettier using style layers; and giving folks a par time using claims.Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-87172100838992162362013-09-15T18:28:00.001-04:002013-09-15T18:28:56.068-04:00Brighter 'Bows<p>The <a href="">HTML5 version</a> of Rainbow features vibrantly colored Rainbows; when porting to C++, I traded off a bit of the brightness of the rainbows for softer intersection behavior. This weekend, I set out to brighten the bows in the C++ port, while retaining nice bow intersections. </p><div style="text-align:center"><div style="display:inline-block"><a href="http://3.bp.blogspot.com/-YkXzAelgxO0/UjYMNMgt4VI/AAAAAAAABpo/XfKM6Lv7c5Y/s1600/rainbow-html5-bright.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-YkXzAelgxO0/UjYMNMgt4VI/AAAAAAAABpo/XfKM6Lv7c5Y/s200/rainbow-html5-bright.png" /></a><p class="caption">html5: bright bows</p></div><div style="display:inline-block"><a href="http://2.bp.blogspot.com/-4wCJKZlQcJo/UjYMPFFdjOI/AAAAAAAABpw/exglh1AK4R4/s1600/rainbow-dull-crop.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-4wCJKZlQcJo/UjYMPFFdjOI/AAAAAAAABpw/exglh1AK4R4/s200/rainbow-dull-crop.png" /></a><p class="caption" >old C++: dull bows</p></div><div style="display:inline-block"><a href="http://4.bp.blogspot.com/-j_Qb5eiq9i4/UjYM2Hi6DFI/AAAAAAAABp4/p6vlQOxj1hk/s1600/rainbow-brighter.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-j_Qb5eiq9i4/UjYM2Hi6DFI/AAAAAAAABp4/p6vlQOxj1hk/s200/rainbow-brighter.png" /></a><p class="caption" >new C++: bright bows</p></div></div><p>As you can see, the C++ version has been improved to have bows as bright as the HTML5 version. </p> <h2>The Goal</h2><p>In Rainbow, the player can split the rainbow they control into multiple "fronts" and drive these fronts separately. Each front leaves a rainbow trail. </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-mCjNvz0lzuk/UjYU8Bo3YfI/AAAAAAAABqo/_KnLXF849Zg/s1600/overlap1.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-mCjNvz0lzuk/UjYU8Bo3YfI/AAAAAAAABqo/_KnLXF849Zg/s150/overlap1.png" /></a><a href="http://1.bp.blogspot.com/-ekOnmIIhbXM/UjYU8LXYzyI/AAAAAAAABqk/JHoBI7C_rls/s1600/overlap2.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-ekOnmIIhbXM/UjYU8LXYzyI/AAAAAAAABqk/JHoBI7C_rls/s150/overlap2.png" /></a><a href="http://2.bp.blogspot.com/-yqpNaRuzlOs/UjYU8FV6FKI/AAAAAAAABqw/s-Cy8ORcFOk/s1600/overlap3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-yqpNaRuzlOs/UjYU8FV6FKI/AAAAAAAABqw/s-Cy8ORcFOk/s150/overlap3.png" /></a></div><p>I would like several conditions to hold:</p><ol><li>Trails freshly produced by a front should draw over older trails.</li><li>Fronts should always remain visible.</li><li>No hard edges should be introduced.</li></ol><p>To justify briefly: (1) arises because I want players to see what they are currently controlling; (2) is important because players should be able to see how much rainbow they have left; and (3) just seems like how magical rainbow substance should behave. </p><h2>The Old Solutions</h2><h3>HTML5</h3><p>In the HTML5 version of Rainbow, the entire rainbow is redrawn each frame with each vertex's depth set based on the number of ticks from the beginning of the rainbow. This method actually fails all three of my ideal conditions in some cases, e.g. when drawing with an older front. </p><h3>C++</h3><p>In the C++ port, the rainbow is accumulated into a framebuffer. This pretty much guarantees that condition (1) holds. Condition (2) is satisfied by always drawing (but not accumulating) the very front of the bow over the top of everything in a different rendering pass. </p><p>This leaves condition (3) -- no hard edges. This is solved by drawing the blow slowly instead of all at once. Specifically, every time a front moves, it draws over its last 10 positions with partially-transparent segments. This has the effect of slowly building up the bow color over 10 steps: </p><div style="text-align:center"><img border="0" src="http://4.bp.blogspot.com/-zd6E2PGi_2w/UjYvXOqIWzI/AAAAAAAABsU/PSbXwVgonGA/s1600/old-front.png" /></div><p>Unfortunately, because it draws over each of the old positions with the same opacity (alpha value) -- set, in an ad-hoc way to 1/8th -- the effective opacity of the bow is only about 73%. </p><h2>The New Solution</h2><p>Let me start by considering a simpler version where we only draw over the last 4 locations. Labeling the segments that get drawn as 1-4 and the locations traversed a-g (both from oldest to newest), one can sketch this diagram: </p><div style="text-align:center"><pre style="display:inline-block;text-align:left"><code><br /> ... ...<br />frame 4: 1 2 3 4<br />frame 3: 1 2 3 4<br />frame 2: 1 2 3 4<br />frame 1: 1 2 3 4<br /> ---------------<br />location: a b c d e f g<br /></code></pre></div><p>I.e. location <code>a</code> will be drawn into by segment 1, and then no others; location <code>b</code> gets drawn by 2 then 1, location <code>c</code> by 3 then 2 then 1, and so on. </p><p>So what opacity value should we pick for segment 4 if we want locations <code>d</code> and beyond to have opacity α<sub>target</sub>? Well, it depends what the next passes (1-3) will draw over it. Let's say that segments 1-3, when drawn, will cover fraction α<sub>next</sub> of a pixel. Then we can select opacity value <i>x</i> for segment 4 by writing down the blending equation: </p><div style="text-align:center"><div style="display:inline-block;text-align:left"><p>α<sub>target</sub> = α<sub>next</sub> + (1 - α<sub>next</sub>)<i>x</i></p><p>α<sub>target</sub> - α<sub>next</sub> = (1 - α<sub>next</sub>)<i>x</i></p><p><i>x</i> = (α<sub>target</sub> - α<sub>next</sub>)/(1 - α<sub>next</sub>)</p></div></div><p>This passes some basic sanity checks -- if we want 100% coverage after segments (1-3) are drawn (i.e. α<sub>target</sub> = 1), we need to draw segment 4 with 100% opacity (i.e. <i>x</i> = 1). Also, if α<sub>next</sub> is greater than α<sub>target</sub> then we get negative values -- which makes sense, as segment 4 can't prevent the subsequently drawn segments from covering the location, so it needs to attempt to preemptively remove coverage. </p> <h3>Implementation</h3><p>Since I'd like the rainbow to smoothly fade in from a cleared start, I chose a "fade" opacity value, <i>f</i> to vary smoothly from 0% coverage (at the trailing edge of the oldest segment) to 100% (at the leading edge of the newest). </p><p>In the pixel shader, other factors that influence opacity -- band color, edge-of-band "antialiasing" texture -- are looked up. Letting their product be called <i>m</i>, the shader sets:</p><div style="text-align:center"><div style="display:inline-block;text-align:left"><p>α<sub>target</sub> = <i>f</i> * <i>m</i></p><p>α<sub>next</sub> = min(1.0, f + 1/10) * <i>m</i></p></div></div><p>These values are used to compute the final opacity value <i>x</i> as outlined above. This results in a variable-opacity front that produces a more vibrant bow:</p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-_MqfkD2A0rU/UjYvfn8N9rI/AAAAAAAABsc/qdaeAkc5ngk/s1600/new-front.png" /></div> <h2>Next Steps</h2><p>I was a bit worried about having a divide in the pixel shader, but profiling on iOS shows negligible effect on frame time. </p><p>Since all of this math is actually done on 8-bit color values, some inaccuracy (and banding) does result. I could avoid this (and the above-mentioned divide) by doing the computation of <i>x</i> with a look-up-table that takes these errors into account. However, the artifacts are not so severe that this is a high priority. </p> <h2>Some Methods That Didn't Work</h2><p>Before settling on the present solution, I tried all sorts of other ideas including multi-pass rendering and different blending modes. While none of them were what I wanted, they did produce some interesting pictures.</p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-0zNjMWyRxpA/UjYgERcoC3I/AAAAAAAABrc/6YlAW1fxQJM/s1600/rainbow-hard.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-0zNjMWyRxpA/UjYgERcoC3I/AAAAAAAABrc/6YlAW1fxQJM/s200/rainbow-hard.png" /></a><a href="http://3.bp.blogspot.com/-RvMpttaEv9Q/UjYgEgDixqI/AAAAAAAABrg/aasumVPSQ3E/s1600/rainbow-max.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-RvMpttaEv9Q/UjYgEgDixqI/AAAAAAAABrg/aasumVPSQ3E/s200/rainbow-max.png" /></a><a href="http://3.bp.blogspot.com/-RA9Fvi-Iir4/UjYgEqI6t4I/AAAAAAAABrk/GgQdUWJCdz4/s1600/rainbow-maybe-the-right-3.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-RA9Fvi-Iir4/UjYgEqI6t4I/AAAAAAAABrk/GgQdUWJCdz4/s200/rainbow-maybe-the-right-3.png" /></a><a href="http://2.bp.blogspot.com/-uIz-pyZQKog/UjYgE7_qvLI/AAAAAAAABsA/nDrWaWzIZLc/s1600/rainbow-not-quite.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-uIz-pyZQKog/UjYgE7_qvLI/AAAAAAAABsA/nDrWaWzIZLc/s200/rainbow-not-quite.png" /></a><a href="http://2.bp.blogspot.com/-BmgzH_s1wJQ/UjYgE_FkLSI/AAAAAAAABrw/Cjf65t6FXrU/s1600/rainbow-proper.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-BmgzH_s1wJQ/UjYgE_FkLSI/AAAAAAAABrw/Cjf65t6FXrU/s200/rainbow-proper.png" /></a><a href="http://2.bp.blogspot.com/-XHbp-qCrxhQ/UjYgFF54lMI/AAAAAAAABr4/YSoOEu6R5BA/s1600/rainbow-what.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-XHbp-qCrxhQ/UjYgFF54lMI/AAAAAAAABr4/YSoOEu6R5BA/s200/rainbow-what.png" /></a></div> Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-19229225720195246582013-09-09T16:04:00.004-04:002013-10-01T12:00:11.301-04:00Making Rktcr Levels: Geometry Types<p>In this <a href="http://tchow.com/games/rktcr/">Rktcr</a> level editing tutorial, I will talk about the different kinds of level geometry available to you in the editor. I will assume familiarity with <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">the basics</a> of Rktcr level editing. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-8VxvmiBUiII/Ui4mtoTlZuI/AAAAAAAABo8/GRoWXfnXWKs/s1600/geom-ingame.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-8VxvmiBUiII/Ui4mtoTlZuI/AAAAAAAABo8/GRoWXfnXWKs/s500/geom-ingame.png" /></a></div><p>As before, Rktcr full version 3.1 or newer is required. (While version 3.0 technically includes the editor, it fails to include a font used thereby.) </p><p>You can grab the level pack for this tutorial <a href="http://tchow.com/games/rktcr/rktcr-leveltut-geom.zip">here</a>. The 'tut-geom' file is the starting point and the 'tut-geom-finished' is the finished level. To make us of them, place the files in your ".rktcr/e_levels" folder, and load into the editor using <kbd>f4</kbd>. <h2>Getting Started</h2><div style="text-align:center"><a href="http://3.bp.blogspot.com/-5XWQxatRFOM/Ui3wHdYKT-I/AAAAAAAABko/zsZ0_2D4yTs/s1600/geom-setup.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-5XWQxatRFOM/Ui3wHdYKT-I/AAAAAAAABko/zsZ0_2D4yTs/s320/geom-setup.png" /></a></div><p>To start this tutorial, create and name a portal side ("start") and gem ("goal"), and save (<kbd>f1</kbd>) this as a new file. I placed the portal and gem far apart because I anticipate adding lots of platform geometry, but you can always place them wherever and adjust it later. (You could also use the starting point from the <a href="http://tchow.com/games/rktcr/rktcr-leveltut-geom.zip">level pack</a>, but it's probably quicker just to create it yourself.) </p><h2>Types of Geometry</h2><p>When you open the create prompt -- <kbd>space</kbd>, then <kbd>backspace</kbd> to delete that pesky space that appears the first time you open it for some reason -- you'll notice quite a few options: </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-g-eqdLM4v_A/Ui3wblyi_yI/AAAAAAAABkw/VQa_Pjtf9L4/s1600/create-options.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-g-eqdLM4v_A/Ui3wblyi_yI/AAAAAAAABkw/VQa_Pjtf9L4/s320/create-options.png" /></a></div><p>We will be using all of the geometry-related options in this tutorial. A brief overview: </p><h3>Create Menu Options</h3><ul><li><code>poly</code> -- create basic straight-line polygons. Workhorse geometry, covered in <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">the basics</a>. Reviewed <a href="#polygon">below</a>.</li><li><code>arc</code>/[<code>-&gt;arc</code>] -- create/[turn selected polygon into] arc-gon -- a polygon where each corner is replaced by a circular arc. Covered <a href="#arcgon">below</a>.</li><li><code>smooth</code> -- create a subdiv-smoothed version the currently selected polyon. Covered <a href="#smooth">below</a>.</li><li><code>dynamic</code> -- create a dynamic (rigid body) version the currently selected polyon. Will be covered in a later tutorial.</li><li><code>side</code> -- create a portal side. See <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">the basics</a>.</li><li><code>gem</code> -- create a portal side. See <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">the basics</a>.</li><li><code>paint</code>, <code>ppoly</code>, <code>ppoly*</code> -- functions relating to level-set-painting geometry. Covered <a href="#paint">below</a>.</li></ul><h2 id="polygon">Polygons</h2><p>First, let's create some polygons; they are a good fundamental starting point, after all. Additionally, the polygon editing controls remain useful for arcgons and smooths. </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-9tlchdK_mxE/Ui3w-PGO3yI/AAAAAAAABk4/DMb7VrdjrMc/s1600/basic-poly.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-9tlchdK_mxE/Ui3w-PGO3yI/AAAAAAAABk4/DMb7VrdjrMc/s320/basic-poly.png" /></a></div><p>The controls for polygon creation are explained in detail in <a href="">the basics</a>, but to briefly review: <kbd>tab</kbd> to toggle edit mode; right-click to select, <kbd>shift</kbd> right-click to multi-select; <kbd>g</kbd>rab, <kbd>s</kbd>cale, and <kbd>r</kbd>otate to move verts; <kbd>e</kbd>xtrude and <kbd>d</kbd>ivide to create more verts; <kbd>x</kbd> to remove verts. </p><h2 id="arcgon">Arc-Gons</h2><p>Now let's add some arc-gons to the level. Create an arc-gon using the prompt and drop into edit mode (<kbd>Space</kbd>, <kbd>a</kbd><kbd>r</kbd><kbd>c</kbd>, <kbd>enter</kbd>, <kbd>tab</kbd>). </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-idOtvYH0vpw/Ui4ASD68xWI/AAAAAAAABlM/LyqOo54EHNQ/s1600/arc-fresh.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-idOtvYH0vpw/Ui4ASD68xWI/AAAAAAAABlM/LyqOo54EHNQ/s320/arc-fresh.png" /></a><a href="http://1.bp.blogspot.com/-jAH-AJYlR-E/Ui4ASF0EFGI/AAAAAAAABlI/pvM1gJO05FI/s1600/arc-edited.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-jAH-AJYlR-E/Ui4ASF0EFGI/AAAAAAAABlI/pvM1gJO05FI/s320/arc-edited.png" /></a></div><p>All the polygon editing controls still work, but now apply to the "cage" around the actual arc-gon. Additionally, left-click dragging will edit the radius associated with the selected corners. </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-mSR0WFMaWmQ/Ui4AdaWTYhI/AAAAAAAABlY/FfJKe1WzeSU/s1600/corner-radius.gif" /></div><p>When two adjacent corners's radii are longer than their edge, their radii are clamped. You can use this to precisely control the radius of a corner by placing a zero-length vertex some (fixed amount) of grid units away: </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-iH_tTa4PPiA/Ui4EHqPP-5I/AAAAAAAABl4/Snj19gZCfkA/s320/rad-verts-1.png" /><img border="0" src="http://2.bp.blogspot.com/-1q035uAV4Io/Ui4EHr-D81I/AAAAAAAABl8/6894i7jATfA/s320/rad-verts-2.png" /></div><p>For example, in the above picture, the marked verts constrain the bottom left and upper right corners to have radii no greater than one grid unit and two grid units, respectively. </p><h3>Converting Polygons to Arc-gons</h3><p>One can also create arc-gons from polygons using the <code>-&gt;arc</code> create command. This will convert the current polygon into an arc-gon with zero-radius corners. </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-AwcA01JoVfk/Ui4CbJ0pGfI/AAAAAAAABlo/x4wZxy9ewGs/s1600/to-arc-pre.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-AwcA01JoVfk/Ui4CbJ0pGfI/AAAAAAAABlo/x4wZxy9ewGs/s320/to-arc-pre.png" /></a><a href="http://2.bp.blogspot.com/-zpWo-8n_sJg/Ui4CbLvmGHI/AAAAAAAABlk/NmvfhikgpBY/s1600/to-arc-post.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-zpWo-8n_sJg/Ui4CbLvmGHI/AAAAAAAABlk/NmvfhikgpBY/s320/to-arc-post.png" /></a></div><p>Here, I've used <code>-&gt;arc</code> on a <kbd>d</kbd>uplicate of the left ceiling polygon, then smoothed the internal vertices by going into edit mode, selecting them, and left-click dragging. </p><p>Really, you could just always work with arc-gons, but sometimes you don't want to worry about accidental left-click drags introducing small-radius corners. </p> <h2 id="smooth">Smoothed Polygons</h2><p>Another way of creating polygons with smooth corners is to use the subdivision modifier. These look "gooier" and a bit more organic to me than arc-gons. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-ongr6XsrOJI/Ui4LsiW2POI/AAAAAAAABmQ/NvpxrvnEGKQ/s1600/smooth-1.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-ongr6XsrOJI/Ui4LsiW2POI/AAAAAAAABmQ/NvpxrvnEGKQ/s200/smooth-1.png" /></a><a href="http://2.bp.blogspot.com/-Y2c6mv8zHaQ/Ui4LsmEj6ZI/AAAAAAAABmU/sN7JNZcTK1A/s1600/smooth-2.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-Y2c6mv8zHaQ/Ui4LsmEj6ZI/AAAAAAAABmU/sN7JNZcTK1A/s200/smooth-2.png" /></a><a href="http://4.bp.blogspot.com/-7VKUmBFiPfU/Ui4Lsv-VaII/AAAAAAAABmc/7xRg906cXDM/s1600/smooth-3.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-7VKUmBFiPfU/Ui4Lsv-VaII/AAAAAAAABmc/7xRg906cXDM/s200/smooth-3.png" /></a></div><p>Above -- from left to right -- I've created a <code>poly</code> and modified it a bit; then selected it and applied <code>smooth</code> (<kbd>space</kbd>, <kbd>s</kbd><kbd>m</kbd><kbd>o</kbd><kbd>o</kbd><kbd>t</kbd><kbd>h</kbd>, <kbd>enter</kbd>); and, finally, dropped into edit mode (<kbd>tab</kbd>) to adjust the vertices more. </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-F4NfGkXt_0I/Ui4NTKOkN2I/AAAAAAAABms/6bCUFQ_L-m8/s1600/smooth-dup.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-F4NfGkXt_0I/Ui4NTKOkN2I/AAAAAAAABms/6bCUFQ_L-m8/s280/smooth-dup.png" /></a></div><p>Note that <kbd>d</kbd>uplicating a smoothed poly will give you a copy of the underlying cage, not the smoothed version, and pressing <kbd>x</kbd> on a smoothed poly will delete just the smoothing. </p><h2 id="paint">Level-Set Painting</h2><div style="text-align:center"><a href="http://4.bp.blogspot.com/-WsHiig5p_UY/Ui4NlBKdfJI/AAAAAAAABm0/RQxzayhNcTU/s1600/with-smooth.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-WsHiig5p_UY/Ui4NlBKdfJI/AAAAAAAABm0/RQxzayhNcTU/s400/with-smooth.png" /></a></div><p>Our level is coming along nicely. Let's finish it off by creating some geometry with level set painting. Painting is a free-form method of specifying geometry; you draw values into a grid, then extract contours of this potential field for use as level geometry. </p><p>To start, we'll need a canvas to paint on. Create one by typing <code>paint</code> at the create prompt (i.e. <kbd>space</kbd>, <kbd>p</kbd><kbd>a</kbd><kbd>i</kbd><kbd>n</kbd><kbd>t</kbd>, <kbd>enter</kbd>). This will immediately drop into painting mode. </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-KFTgjA6z1cw/Ui4TDDCfuNI/AAAAAAAABnE/JZ82N8XL3pc/s1600/paint-pos.gif" /><img border="0" src="http://1.bp.blogspot.com/-oDGsTbt8lSs/Ui4TDNVDpAI/AAAAAAAABnI/0w7teuYmNBQ/s1600/paint-neg.gif" /></div><p>In painting mode, you add material with left-click and remove it with right-click. Red lines show the level geometry that (may) be created from the current paint. The yellow line shows the outline of the canvas. This will be automatically resized if you paint outside its borders. </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-VOS_FEkKbgY/Ui4X4j6OnqI/AAAAAAAABnc/c5L63FdHJFg/s1600/brushes.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-VOS_FEkKbgY/Ui4X4j6OnqI/AAAAAAAABnc/c5L63FdHJFg/s600/brushes.png" /></a></div><p>The brush has two parameters, a radius (modify with <kbd>shift</kbd>-mousewheel) and a falloff distance (modify with <kbd>ctrl</kbd>-mousewheel). The above image shows a few options. The falloff doesn't really do much unless you start painting a lot of positive and negative strokes, in which case it changes (a bit) how the generated geometry moves. </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-tAR--4q7VZA/Ui4Z6RNJr8I/AAAAAAAABns/13aTc4mZQ4I/s1600/grid-1.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-tAR--4q7VZA/Ui4Z6RNJr8I/AAAAAAAABns/13aTc4mZQ4I/s200/grid-1.png" /></a><a href="http://1.bp.blogspot.com/-rJXHXn1d42Y/Ui4Z6QYRJTI/AAAAAAAABno/NFBJ1dFanDY/s1600/grid-2.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-rJXHXn1d42Y/Ui4Z6QYRJTI/AAAAAAAABno/NFBJ1dFanDY/s200/grid-2.png" /></a><a href="http://3.bp.blogspot.com/-fJUeIkhMyJA/Ui4Z6c__SGI/AAAAAAAABnw/HADgXXloUp8/s1600/grid-3.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-fJUeIkhMyJA/Ui4Z6c__SGI/AAAAAAAABnw/HADgXXloUp8/s200/grid-3.png" /></a></div><p>If you are painting large areas, the editor can bog down. In this case, you can use <kbd>up arrow</kbd> and <kbd>down arrow</kbd> keys to adjust the painting grid resolution. This is non-destructive (you can always switch back to an old resolution without a problem). </p><p>Note also that some simplification is always run on the output level geometry, so using finer grids may not actually change the number of vertices in your level. </p><h3>Adding Paint-Polygons</h3><p>If you have been playtesting your level, you will have noticed that your awesome paint doesn't actually appear in the game yet. This is because you need to create paint polygons to pull information out of the paint. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-klVsAwU9Asw/Ui4kLHJaZlI/AAAAAAAABoI/cev3wmU2_Dg/s1600/ppoly-1.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-klVsAwU9Asw/Ui4kLHJaZlI/AAAAAAAABoI/cev3wmU2_Dg/s300/ppoly-1.png" /></a><a href="http://2.bp.blogspot.com/-O3Tvrayl2fQ/Ui4kLLotJ3I/AAAAAAAABoM/uKkspsa3DLg/s1600/ppoly-2.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-O3Tvrayl2fQ/Ui4kLLotJ3I/AAAAAAAABoM/uKkspsa3DLg/s300/ppoly-2.png" /></a></div><p>The <code>ppoly*</code> command (i.e. <kbd>space</kbd>, <kbd>p</kbd><kbd>p</kbd><kbd>o</kbd><kbd>l</kbd><kbd>y</kbd><kbd>*</kbd>, <kbd>enter</kbd>) creates paint polygons for all contours in the currently selected canvas, while <code>poly</code> creates a polygon based on a seed point at your current mouse cursor. </p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-IkyZ0PPYtrM/Ui4khYv5LSI/AAAAAAAABoY/n93-ZaZYHt4/s1600/ppoly-3.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-IkyZ0PPYtrM/Ui4khYv5LSI/AAAAAAAABoY/n93-ZaZYHt4/s300/ppoly-3.png" /></a><a href="http://4.bp.blogspot.com/-3Ek0QBmfzvE/Ui4khsWMVMI/AAAAAAAABoc/NL29SVoeTaU/s1600/ppoly-4.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-3Ek0QBmfzvE/Ui4khsWMVMI/AAAAAAAABoc/NL29SVoeTaU/s300/ppoly-4.png" /></a></div><p>Once created, paint polygons can be <kbd>g</kbd>rabbed to offset them from their canvas positions, or deleted with <kbd>x</kbd> (useful for removing shards). Additionally, changes in the original canvas will be reflected in the extracted outlines. This can be useful for minor edits to platform shapes. </p><p>Note that sometimes -- due to, e.g., topological changes in the canvas -- one can end up with multiple ppoly's for the same contour. This results in overlapping geometry and is generally bad news for your levels. </p><h2>Wrapping up</h2><p>In this tutorial, I showed you how to use <a href="http://tchow.com/games/rktcr/">Rktcr</a>'s four different types of level geometry: basic <a href="#polygon">polygons</a>, the somewhat smoother <a href="#arcgon">arc-gons</a>, the organic looking <a href="#smooth">smooth</a> modifier, and the freeform <a href="#paint">paint</a>-based geometry. </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-bGIn3DTD8Qw/Ui4k69CHFeI/AAAAAAAABoo/Vel8NPmlMQ4/s1600/geom-with-ppoly.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-bGIn3DTD8Qw/Ui4k69CHFeI/AAAAAAAABoo/Vel8NPmlMQ4/s500/geom-with-ppoly.png" /></a></div><p>I find that each type of geometry lends itself to a different style of level -- as you'll notice in the game -- but that it can occasionally be useful to mix them up for specific situations. </p><h2>Next Steps</h2><p>Now that you are familiar with the various ways to create level geometry, it's time to add details and graphical polish. In upcoming tutorials, I'll talk about adding <a href="http://news.tchow.com/2013/09/making-rktcr-levels-dynamics.html">dynamic objects and constraints</a>; <a href="http://news.tchow.com/2013/09/making-rktcr-levels-disruptables.html">working with disruptable platforms and gems</a>; <a href="http://news.tchow.com/2013/10/making-rktcr-levels-bursts.html">adding bursts</a>; making your level prettier using style layers; and giving folks a par time using claims. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com2tag:blogger.com,1999:blog-4470168163688426003.post-75777798780094217172013-09-07T15:48:00.000-04:002013-10-01T11:59:51.090-04:00Making Rktcr Levels: The Basics<p>Now that <a href="http://tchow.com/games/rktcr/">Rktcr</a>'s level editor is percolating out to those that purchased the game on Desura, it seems like a good idea to go about documenting how to use it. The editor does have a few rough edges (save often! there are crashes), but it is the thing I used to create all the levels in the game. </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-WtDxxe0vF34/UitkOD0KTDI/AAAAAAAABj8/EKtK69T9faA/s1600/ingame.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-WtDxxe0vF34/UitkOD0KTDI/AAAAAAAABj8/EKtK69T9faA/s320/ingame.png" /></a></div><p>In this tutorial, I will show you how to use Rktcr's editor to create a simple challenge level that will appear in the game. </p><h2>Video</h2><p>There is also a video version of the tutorial, for those of you who are into that kind of thing:</p><div style="text-align:center"><iframe width="560" height="315" src="//www.youtube.com/embed/18GkhbRzEoc" frameborder="0" allowfullscreen></iframe></div><p>If you, like me, enjoy textural tutorials, read on...</p><h2>Preliminaries</h2><p>Rktcr stores data in two directories: the "game directory" (the directory where executable is located) and the "user data directory" (a system-specific directory). The idea is that when upgrading/whatever you should be able to delete your game directory and not lose, e.g., saved teams. </p><p>The game directory is located wherever you (or desura) put it. The user data directory is located in your home directory (that is, at "~/.rktcr") on Linux and OSX; and in your user profile directory (that is, at "%UserProfile%\rktcr", which usually expands to something like "Documents\rktcr") on Windows. </p><p>This tutorial is going to be written from a Linux/OSX point of view, which means I will use forward slash as my path separator and ".rktcr" to refer to the user data directory. </p><h2>Level File Handling</h2><p>Before I go into how to actually create levels, it's important to realize that levels in Rktcr exist in two forms: editable and playable. Editable levels are what you load and edit in the editor (not so complicated, eh?), and are in a text format aimed at extensiblity and versioning. Playable levels are what you actually play in the game, and are in a binary format optimized for loading speed. </p><p>Editable user levels live in the ".rktcr/e_levels" or "rktcr/e_userlevels" directories, while playable user levels live in the ".rktcr/levels" or "rktcr/userlevels" directories. Playable levels are generated by Rktcr from their editable counterparts when saved in the editor (or any time the game is run and the playable levels have older timestamps). </p><h2>Starting the Editor</h2><p>You start the editor by passing the command line parameter "edit" to Rktcr. This is going to require that you use a command-line shell (or write a small script). Using a command line interface is probably something you should already know how to do, if only because it is the easiest way to actually use your computer. (Yep, that says a lot about me right there, doesn't it.) </p><h3>Windows</h3><p>Under Windows, tap <kbd>winkey</kbd> to bring up the start menu, type <code>cmd.exe</code>, and press <kbd>enter</kbd>. You should now have a nice cmd.exe shell open. (For earlier versions of windows, <kbd>winkey</kbd>-<kbd>r</kbd> might be more your speed.) Use the `cd` command to change the current working directory to Rktcr's game directory. Now type `rktcr.exe edit` to start Rktcr in editing mode. </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-asT9xAgsk70/Uitt7rnAL2I/AAAAAAAABkM/5MkG4jAcpw8/s600/rktcr-cmd.png" /></div><h3>OSX</h3><p>With OSX, launching a terminal is as simple as pressing <kbd>command</kbd>-<kbd>space</kbd> to open spotlight, typing <code>terminal</code> (or a short prefix thereof) and slapping <kbd>enter</kbd>. Once you've got a terminal open, use `cd` to change to the rktcr directory, and then run Rktcr from within the .app bundle as `/rktcr.app/Contents/MacOS/rktcr edit` </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-OaRUZ2rSNKw/UitwgVVKrTI/AAAAAAAABkY/2k9UbeCbMYw/s600/rktcr-osx.png" /></div><h3>Linux</h3><p>You use Linux and you don't know this stuff? That's probably a really good sign as far as the maturity of your distro as a desktop OS. Unfortunately, because there are so many different Linux distributions and configurations, you're on your own as to actually how to find a terminal emulator. (FWIW, I get one by pressing meta-enter, but that's probably just me.) </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-gr6wHt20lHI/UitDvjKxVNI/AAAAAAAABgc/gpSZSGdQKOc/s600/linux-terminal.png" /></div><p>Once you find it, though, it's a simple job of `cd`-ing to the rktcr directory and invoking `./rktcr edit`. </p><h2>Your First Level</h2><p>When you launch the Rktcr editor you'll arrive at a blank screen: </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-XdhhLkTDjxs/UitEuKty1LI/AAAAAAAABgk/uLJHr0Tqc88/s1600/editor.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-XdhhLkTDjxs/UitEuKty1LI/AAAAAAAABgk/uLJHr0Tqc88/s320/editor.png" /></a></div><p>This is your level-in-progress. You can move the view by middle-click dragging, and zoom using the mouse wheel. (On OSX, this is command-left-click dragging and two-finger up/down motion, respectively.) Of course, there's nothing in the level to see, so these motions don't do much yet. </p><p>The arrow in the bottom right shows the current up direction and mirroring. You can change it with <kbd>[</kbd>, <kbd>]</kbd>, and <kbd>p</kbd>, but -- since all challenge levels are played in the standard orientation (arrow up, red on the right) -- you shouldn't. </p><h3>Creating the Portal and Gem</h3><p>All challenge levels need a portal side to start at and one or more gems to collect. To create them we use the creation prompt. Press <kbd>space</kbd> to open the prompt (and then press <kbd>backspace</kbd> to delete the extraneous space that tends to appear the first time you do this). You are presented with a cursor and a list of options to type: </p><div style="text-align:center"><a href="http://1.bp.blogspot.com/-5lxTyxYuMWE/UitHrC_drEI/AAAAAAAABg4/Z-SpINcjfHk/s1600/create-prompt.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-HJtBFO0PJlc/UitIP4fVkKI/AAAAAAAABhA/8h20yYAc4gU/s320/create-prompt.png" /></a></div><p>Let's create a portal side. Type <kbd>s</kbd><kbd>i</kbd> (followed by <kbd>tab</kbd> to autocomplete or the rest of "side" otherwise). Now press <kbd>enter</kbd> and a portal side should appear at your mouse cursor: </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/--AUvfBUDugE/UitHlrqKECI/AAAAAAAABgw/BUQddCSDTCc/s1600/created-side.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/--AUvfBUDugE/UitHlrqKECI/AAAAAAAABgw/BUQddCSDTCc/s320/created-side.png" /></a></div><p>Repeat the process to create a gem -- <kbd>space</kbd>, type <kbd>g</kbd><kbd>e</kbd><kbd>m</kbd>, press <kbd>enter</kbd>, and you have a gem at your mouse cursor: </p><div style="text-align:center"><img border="0" src="http://4.bp.blogspot.com/-TlikJr0Vxc4/UitJjKsJ1TI/AAAAAAAABhQ/_cgLq_OJ97k/s320/gem-prompt.png" /><img border="0" src="http://4.bp.blogspot.com/-US4RqOfJjuc/UitI8npv1QI/AAAAAAAABhI/DpAcM0uqMiw/s1600/create-gem.png" /></div><p>Okay! It isn't much of a level, but it's a start. You can select the gem or portal side by using the right mouse button. Moving the currently selected object is done by pressing <kbd>g</kbd> ("grab"), moving the mouse, and pressing the left mouse button to set the object down. (Right mouse button will cancel a movement operation.) You can also delete the currently selected object with <kbd>x</kbd>. </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-Ccq2uNkahII/UitNlzOrW3I/AAAAAAAABhw/JXkjNl7KdBc/s1600/move-gem.gif" /></div><p>When the portal is selected, the left and right arrows can be used to rotate it. With a bit of grabbing and rotating, we can make an easy-to-win level: </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-poJ-exKTZ-w/UitOXakiadI/AAAAAAAABh4/4lRWOB3Fj2I/s1600/simple-level.png" /></div><p>If you want to give it a try, select the portal (right click) and press <kbd>enter</kbd>. This will start at the selected portal: </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-uOwqnlsySfU/UitO5MlXgFI/AAAAAAAABiA/h6fZrS18iyA/s1600/playing.png" /></div><p>When playing this way, <kbd>escape</kbd> will take you back to the editor. </p><h2>Naming Things</h2><p>If you get the gem when playing, you may notice some odd messages in the terminal: </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-cSd7hd_DqO8/UitQRzaD-9I/AAAAAAAABiM/8ihsARXPHro/s1600/noname-message.png" /></div><p>Why does the style warning have no level name? Why is the path named so weirdly? It's because nothing in the level -- the portal, the gem, or the level itself -- has a correct name yet. </p><h3>Saving: Naming the Level</h3><p>Naming the level is straightforward. Press <kbd>f1</kbd> to open up the save prompt, type a name for the level, and press <kbd>enter</kbd>: </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-dhZIK4MzG_E/UitRY2GnpYI/AAAAAAAABiU/mNKN7O6Azz0/s320/saving.png" /></div><p>After pressing enter, a file called "tut00" (or whatever you named the level) should appear in both your ".rktcr/e_levels" and ".rktcr/levels" directories. The one in "e_levels" is the editable version, the one in "levels" is the playable version. </p><h3>Edit Mode: Naming the Gem and Portal</h3><p>To name the gem and the portal, you'll need to use edit mode. You access edit mode for an object by pressing <kbd>tab</kbd> while the object is selected. In edit mode, you see a list of values, navigate that list with the up and down arrows, and open up a prompt to edit a value by pressing <kbd>enter</kbd>. You leave edit mode by pressing <kbd>escape</kbd>. </p><div style="text-align:center"><img border="0" src="http://1.bp.blogspot.com/-uZT6YGg9a2M/UitaLBwG9JI/AAAAAAAABi8/3mGWivI3jpk/s1600/name-side.gif" /></div><p>For challenge levels, it is the convention to name the portal "start" and the gem "goal" (or "goal1", "goal2", and so on for multiple gems). </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-cEXUO6cJyRY/UitZi8JIMvI/AAAAAAAABis/8dvZDpLroVg/s1600/name-side.png" /><img border="0" src="http://4.bp.blogspot.com/-pcvhZv6_bVw/UitZi8_wQaI/AAAAAAAABiw/D9HammEC-_I/s1600/name-gem.png" /></div><p>Now if you playtest the level (right click on the portal, press <kbd>enter</kbd>) and get the gem, the messages make more sense: </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-m6bn4vVvkkk/UitbK-7_0oI/AAAAAAAABjI/NyTveY0WgBM/s1600/name-message.png" /></div><p>By the way if, you quit the editor <b>(remember to save!)</b> and start the game now, you'll see your level at the bottom of the challenge files in the "impossible" category. Category is determined by name; if you'd like your level to be in the "basic" category, start its name with "c-"; for "tricky" use "b-"; and for "impossible" use "a-". </p><h2>Creating Some Geometry</h2><p><b>Note:</b> if you happen to have left the editor and returned you can load your level again by pressing <kbd>f4</kbd>. </p><p>This level is perhaps a bit too straightforward, so let's modify it by adding a platform. Use the creation prompt to make a 'poly' object (i.e. <kbd>space</kbd>, <kbd>p</kbd><kbd>o</kbd><kbd>l</kbd><kbd>y</kbd>, <kbd>enter</kbd>): </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-_ywavng0AQ8/Uite7uk7x1I/AAAAAAAABjU/js0TseTRakU/s1600/poly.png" /></div><p>Of course, just having a platform sitting there isn't very interesting. To change the shape of the platform, use edit mode (<kbd>tab</kbd> to enter, <kbd>tab</kbd> to leave -- I know this is inconsistent, but I never got around to changing it). </p><div style="text-align:center"><img border="0" src="http://2.bp.blogspot.com/-HOOvhhEeJFI/UitiCNCRNbI/AAAAAAAABjg/tccf6VTNuI8/s1600/poly-edit.png" /></div><p>Edit mode keys are reasonably similar to <a href="http://www.blender.org">Blender</a>. There are a fair few functions, so I'll just list them: </p><h3>Editor Controls (Polygon Edit Mode)</h3><ul><li>right click -- select nearest vertex. (Or toggle selection state of vert, if <kbd>shift</kbd> is held.)</li><li><kbd>a</kbd> -- select/deselect all vertices.</li><li><kbd>g</kbd> -- grab (translate) selected vertices.</li><li><kbd>r</kbd> -- rotate selected vertices. (Rotation angles quantized if <kbd>shift</kbd> is held.)</li><li><kbd>s</kbd> -- scale selected vertices.</li><li><kbd>d</kbd> -- subdivide edges between selected vertices.</li><li><kbd>x</kbd> -- delete selected vertices.</li><li><kbd>e</kbd> -- extrude selected vertices.</li><li><kbd>f</kbd> -- flip direction of curve (the long triangles on the edges should point to the inside; if they don't, use <kbd>f</kbd>).</li></ul><p>Press <kbd>0</kbd> through <kbd>9</kbd> to add a grid. Press the same number again to remove it. The grid is used to quantize translations. Press <kbd>ctrl</kbd> to momentarily toggle. Press <kbd>shift</kbd> to snap to grid. </p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-2imhqHOwG1I/UitiHH_4MSI/AAAAAAAABjs/OyvYvc3nz8I/s1600/poly-edited.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-2imhqHOwG1I/UitiHH_4MSI/AAAAAAAABjs/OyvYvc3nz8I/s200/poly-edited.png" /></a><a href="http://1.bp.blogspot.com/-jtnMUcEIHEg/UitizejqvkI/AAAAAAAABjw/Pbns43MnOWU/s1600/poly-playtest.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-jtnMUcEIHEg/UitizejqvkI/AAAAAAAABjw/Pbns43MnOWU/s200/poly-playtest.png" /></a></div><p>With a bit of editing, your boring platform can become something more interesting. Be sure to save and playtest often. </p><h2>Wrapping Up</h2><p>In this tutorial, I introduced Rktcr's editor; showed you how to create a very basic user level with a single portal, gem, and platform; demonstrated how to name the portal and gem so that path names would make sense; and talked about how to edit the platform to make the level more interesting. </p><p>In the process, I covered the following basic controls: </p><h3>Editor Controls (not in Edit Mode)</h3><ul><li><kbd>f4</kbd> -- load prompt; type name and press <kbd>enter</kbd> to load. <kbd>Escape</kbd> cancels.</li><li><kbd>f1</kbd> -- save prompt; type name and press <kbd>enter</kbd> to save. <kbd>Escape</kbd> cancels.</li><li>middle-click drag -- pan view (command-left-click drag works on OSX).</li><li>mouse wheel -- zoom view (two-finger scroll gesture works on OSX).</li><li><kbd>[</kbd>, <kbd>]</kbd>, <kbd>p</kbd> -- adjust view rotation and mirroring (not very useful for challenge levels).</li><li><kbd>space</kbd> -- open create prompt; type and press <kbd>enter</kbd> to create object. <kbd>Escape</kbd> cancels.</li><li>right-click -- select object.</li><li><kbd>g</kbd> -- grab object. Move mouse to translate; left-click to set down, right-click to cancel.</li><li><kbd>tab</kbd> -- edit mode.</li><li><kbd>x</kbd> -- delete selected object.</li><li>left/right arrow -- rotate currently selected portal side.</li></ul><h2>Next Steps</h2><p>These basic controls and ideas will serve you well in creating levels, but there is much more to explore. In upcoming tutorials, I will cover <a href="http://news.tchow.com/2013/09/making-rktcr-levels-geometry-types.html">making your level's geometry smoother</a> using subdivs, arc-gons, and paint; changing your level's physics by adding <a href="http://news.tchow.com/2013/09/making-rktcr-levels-dynamics.html">dynamic objects and constraints</a>; <a href="http://news.tchow.com/2013/09/making-rktcr-levels-disruptables.html">working with disruptable platforms and gems</a>; <a href="http://news.tchow.com/2013/10/making-rktcr-levels-bursts.html">adding bursts</a>; making your level prettier using style layers; and giving folks a par time using claims. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-6422172864241383252013-09-06T20:22:00.001-04:002013-09-07T16:08:08.816-04:00Rktcr version 3.1: User Levels<p>I'm pleased to announce <a href="http://tchow.com/games/rktcr/">Rktcr</a> version 3.1, featuring the ability to load user levels, a few bugfixes, and a more paranoid startup routine. The <a href="http://tchow.com/games/rktcr/#demo">demo version</a> on the Rktcr web page has already been updated, and the demo and full versions should be making their way onto <a href="http://www.desura.com/games/rktcr">Desura</a> early in the upcoming week. </p><h2>Paranoid Startup</h2><p>If Rktcr ever detects that it failed to make it through graphics and sound initialization, it will reset its graphics settings to something very conservative on the next load. This -- one hopes -- should work around a problem on (some) Intel GPUs where the program fails to work when antialiasing is turned on. Also, it should help to prevent you from shooting yourself in the foot by selecting unworkable settings in the configuration menu. </p><h2>User Levels</h2><p><b>(Full version only.)</b></p><p>The full version of Rktcr now supports loading additional challenge levels from the "%UserProfile%\rktcr\levels" (Windows) or "~/.rktcr/levels" (Linux/OSX) directory. (Or the "rktcr/userlevels" directory, if you want.) </p><p>In celebration, I've created a pack of challenge levels I call "Meditations on Bouncing": </p><div style="text-align:center"><a href="http://3.bp.blogspot.com/-Eq5QZufCrdI/UipsM3qznNI/AAAAAAAABfs/eutURDUwt0c/s1600/mb01-simple.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-Eq5QZufCrdI/UipsM3qznNI/AAAAAAAABfs/eutURDUwt0c/s200/mb01-simple.png" /></a><a href="http://2.bp.blogspot.com/-tOePKnT2ALU/UipsM91ctAI/AAAAAAAABfw/f89IJWNm-uE/s1600/mb02-wall.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-tOePKnT2ALU/UipsM91ctAI/AAAAAAAABfw/f89IJWNm-uE/s200/mb02-wall.png" /></a><a href="http://4.bp.blogspot.com/-Ja3BU1uygqA/UipsM2hEtbI/AAAAAAAABf0/SeEcJm9cuo0/s1600/mb03-steps.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-Ja3BU1uygqA/UipsM2hEtbI/AAAAAAAABf0/SeEcJm9cuo0/s200/mb03-steps.png" /></a><a href="http://1.bp.blogspot.com/-wjxQjiSe6x4/UipsNT3Sy_I/AAAAAAAABf4/AyjGsv4W5_I/s1600/mb04-reflex.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-wjxQjiSe6x4/UipsNT3Sy_I/AAAAAAAABf4/AyjGsv4W5_I/s200/mb04-reflex.png" /></a><a href="http://4.bp.blogspot.com/-iciupE_90CU/UipsNoZ4IUI/AAAAAAAABgA/64tjbtlqf7o/s1600/mb05-herring.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-iciupE_90CU/UipsNoZ4IUI/AAAAAAAABgA/64tjbtlqf7o/s200/mb05-herring.png" /></a></div></p>You can download the level pack <a href="http://tchow.com/games/rktcr/rktcr-levelpack-mb.zip">here</a>. Though do bear in mind that the full version of Rktcr is required. (Really, shouldn't you have <a href="http://www.desura.com/games/rktcr">bought it</a> by now?) </p><h2>Level Editor</h2><p><b>(Full version only.)</b></p><p>You can create your own levels by using the built-in editor -- accessible by running rktcr with the command line parameter 'edit'. I've created a tutorial series to help you muddle through the editor's undocumented features; the first of which is <a href="http://news.tchow.com/2013/09/making-rktcr-levels-basics.html">over here</a>. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-29557618782585532262013-09-03T16:18:00.001-04:002013-09-03T16:18:00.346-04:00"Let's Play Rktcr" Roundup<p>The let's plays of <a href="http://tchow.com/games/rktcr/">Rktcr</a> continue to accrue. The general consensus seems to be "this seems intriguing, but is awkward to pick up and play." I take this as an indication that there aren't really enough challenges that are possible at the low end of the difficulty curve. </p><p>Suggestions for easing this initial portion of the difficulty curve are welcome, of course. </p><h2>The Videos</h2><div style="text-align:center"><iframe width="560" height="315" src="//www.youtube.com/embed/LFbeBJbQ6G4?list=PLzceGO2K6_NRrxdGmFz7kx0a60vDnklZz" frameborder="0" allowfullscreen></iframe></div><p>These are the let's plays of which I am aware. I will add more as I learn of them. (Comments and <a href="mailto:ix@tchow.com">e-mail</a> are both welcome.) </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-7576400841972731212013-08-26T14:03:00.000-04:002013-08-26T14:03:38.357-04:00Learn to Play Rktcr<p>There have been a few let's plays of Rktcr recently -- which you should <a href="http://www.youtube.com/watch?v=WVCrxYq2Ky4">definitely</a> <a href="http://www.youtube.com/watch?v=rTmlXYbThkM">check</a> <a href="http://www.youtube.com/watch?v=r-Uv3tHZw5Y">out</a> -- It's really fun to see people picking up the game and getting into it. </p><p>However, the general conclusion from these folks seems to be "wow, I could definitely solve this if I had more time to put into it." You'll see a lot of failing in these videos. This led me to create my own quick Rktcr video series... </p><h2>Learn To Play Rktcr</h2><p>This series is aimed at teaching you (the Rktcr neophyte) basic tools and habits that will make you an effective player and -- ideally -- decrease both my frustration when I'm watching you and your frustration as you are playing. </p><div style="text-align:center"><iframe width="560" height="315" src="//www.youtube.com/embed/4CHsngjWGOA?list=PLzceGO2K6_NT2wrsbR-RS9HJcjbIhgEF_" frameborder="0" allowfullscreen></iframe></div><p>There are ten videos in the playlist, and I feel like I really hit my stride around video four or five. </p><p>Note also that the sound quality on my webcam microphone is somewhat poor. It's listenable, but I will keep this in mind when recording future videos. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-36997206466202974462013-08-22T16:36:00.000-04:002013-08-22T16:36:00.696-04:00Rktcr Wallpapers and Posters<p>I've been spending most of my <a href="http://tchow.com/games/rktcr/">Rktcr</a>-related time over the last few days sending out free copies to reviewers and lets-players. This is actually quite time-consuming, since I'm writing a new blurb for each person. I know it would be simpler to copy-paste, but it seems only fair that if they are going to invest the time to check out the game, I should invest the time to write something for just them. </p><p>However, I have put a little time into making cool assemblages of Rktcr sprites. These might work well as posters or desktop wallpapers (though they are perhaps a bit busy for a desktop with icons). Regardless, I like the way they look. </p><div style="text-align:center"><img border="0" src="http://3.bp.blogspot.com/-J2hwVi3G9Ds/UhZ0G9dr7qI/AAAAAAAABbo/RDsaiWocet8/s1600/rktcr-posters.jpeg" /></div><p>I can make these in pretty much any aspect ratio and resolution, so if you would like a custom size, let me know via <a href="mailto:ix@tchow.com">e-mail</a> or comment. </p><h2>Posters</h2><p>These were designed for 11x17 (top row) or 8.5x11 (bottom row) paper. Feel free to download and print.</p><div style="text-align:center"><a href="http://4.bp.blogspot.com/-cc3cuR9Dx-g/UhZ09HbYBCI/AAAAAAAABbw/SmKihiSoKPo/s1600/rktcr-teams-5100x3300-300.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-cc3cuR9Dx-g/UhZ09HbYBCI/AAAAAAAABbw/SmKihiSoKPo/s200/rktcr-teams-5100x3300-300.png" /></a><a href="http://2.bp.blogspot.com/-m2wJ9q7Gg4Y/UhZ09YRVz0I/AAAAAAAABb4/M1xTXKW9m-I/s1600/rktcr-people-5100x3300-300.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-m2wJ9q7Gg4Y/UhZ09YRVz0I/AAAAAAAABb4/M1xTXKW9m-I/s200/rktcr-people-5100x3300-300.png" /></a><a href="http://4.bp.blogspot.com/-wjs3vEVy25Y/UhZ084kXWnI/AAAAAAAABb0/-gFhnQDMOH4/s1600/rktcr-vehicles-5100x3300-300.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-wjs3vEVy25Y/UhZ084kXWnI/AAAAAAAABb0/-gFhnQDMOH4/s200/rktcr-vehicles-5100x3300-300.png" /></a></div><div style="text-align:center"><a href="http://1.bp.blogspot.com/-a_xN1Hm1esU/UhZ1JyrtupI/AAAAAAAABcI/lm71hBc8870/s1600/rktcr-teams-3300x2550-300.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-a_xN1Hm1esU/UhZ1JyrtupI/AAAAAAAABcI/lm71hBc8870/s200/rktcr-teams-3300x2550-300.png" /></a><a href="http://1.bp.blogspot.com/-KDfSFqX3LdU/UhZ1J3rt1EI/AAAAAAAABcM/QW6HUCP7YCM/s1600/rktcr-people-3300x2550-300.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-KDfSFqX3LdU/UhZ1J3rt1EI/AAAAAAAABcM/QW6HUCP7YCM/s200/rktcr-people-3300x2550-300.png" /></a><a href="http://3.bp.blogspot.com/-L1yMQ_KB-v0/UhZ1Jy0EJlI/AAAAAAAABcQ/UhhqxgDg1JA/s1600/rktcr-vehicles-3300x2550-300.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-L1yMQ_KB-v0/UhZ1Jy0EJlI/AAAAAAAABcQ/UhhqxgDg1JA/s200/rktcr-vehicles-3300x2550-300.png" /></a></div><h2>Wallpapers</h2><p>I included some dark variants for the desktop wallpapers because, well, you never know.</p><div style="text-align:center"><a href="http://2.bp.blogspot.com/-gwJ1X2nFqzI/UhRAHf3dwbI/AAAAAAAABUs/NfyYXSkJ8EA/s1600/mix-light-4x3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-gwJ1X2nFqzI/UhRAHf3dwbI/AAAAAAAABUs/NfyYXSkJ8EA/s200/mix-light-4x3.png" /></a><a href="http://4.bp.blogspot.com/-OvAjoB7qszo/UhRAI7K9-jI/AAAAAAAABVg/BFNRYINjasI/s1600/people-light-4x3.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-OvAjoB7qszo/UhRAI7K9-jI/AAAAAAAABVg/BFNRYINjasI/s200/people-light-4x3.png" /></a><a href="http://2.bp.blogspot.com/-EUk_i97Foew/UhRAKHBQ8uI/AAAAAAAABVs/gXHU-UrXbNQ/s1600/vehicle-light-4x3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-EUk_i97Foew/UhRAKHBQ8uI/AAAAAAAABVs/gXHU-UrXbNQ/s200/vehicle-light-4x3.png" /></a></div><div style="text-align:center"><a href="http://2.bp.blogspot.com/-S0Pccy-RW50/UhRAGqNBNRI/AAAAAAAABUo/hkUNf85Dh04/s1600/mix-dark-4x3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-S0Pccy-RW50/UhRAGqNBNRI/AAAAAAAABUo/hkUNf85Dh04/s200/mix-dark-4x3.png" /></a><a href="http://2.bp.blogspot.com/-4koGodSQC1c/UhRAH533pFI/AAAAAAAABVA/rWH-e4FL9DU/s1600/people-dark-4x3.png" imageanchor="1" ><img border="0" src="http://2.bp.blogspot.com/-4koGodSQC1c/UhRAH533pFI/AAAAAAAABVA/rWH-e4FL9DU/s200/people-dark-4x3.png" /></a><a href="http://3.bp.blogspot.com/-e01i4uFjLeo/UhRAJIB9HfI/AAAAAAAABVc/rRZ_q3h5olM/s1600/vehicle-dark-4x3.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-e01i4uFjLeo/UhRAJIB9HfI/AAAAAAAABVc/rRZ_q3h5olM/s200/vehicle-dark-4x3.png" /></a></div><div style="text-align:center"><a href="http://4.bp.blogspot.com/-rvp9BVt5JHs/UhRAGu_o9pI/AAAAAAAABUg/bNOaLmTd3eE/s1600/mix-light-16x9.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-rvp9BVt5JHs/UhRAGu_o9pI/AAAAAAAABUg/bNOaLmTd3eE/s200/mix-light-16x9.png" /></a><a href="http://1.bp.blogspot.com/-iEbzdjQKUXI/UhRAIaYlTNI/AAAAAAAABVE/IRs0zIsmX4k/s1600/people-light-16x9.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-iEbzdjQKUXI/UhRAIaYlTNI/AAAAAAAABVE/IRs0zIsmX4k/s200/people-light-16x9.png" /></a><a href="http://4.bp.blogspot.com/-nahrF8vUFBE/UhRAJrwEX-I/AAAAAAAABVk/x7OzhKVsmuI/s1600/vehicle-light-16x9.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-nahrF8vUFBE/UhRAJrwEX-I/AAAAAAAABVk/x7OzhKVsmuI/s200/vehicle-light-16x9.png" /></a></div><div style="text-align:center"><a href="http://3.bp.blogspot.com/-bhhdztEATfc/UhRAGiXELSI/AAAAAAAABUk/m6LT8jpMb9w/s1600/mix-dark-16x9.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-bhhdztEATfc/UhRAGiXELSI/AAAAAAAABUk/m6LT8jpMb9w/s200/mix-dark-16x9.png" /></a><a href="http://4.bp.blogspot.com/-d-0vx8VgLRU/UhRAHquC2rI/AAAAAAAABU8/wFqTunTUBqo/s1600/people-dark-16x9.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-d-0vx8VgLRU/UhRAHquC2rI/AAAAAAAABU8/wFqTunTUBqo/s200/people-dark-16x9.png" /></a><a href="http://1.bp.blogspot.com/-FruqLV_oUXw/UhRAI0dkt8I/AAAAAAAABVM/ZzEX0JSnXW8/s1600/vehicle-dark-16x9.png" imageanchor="1" ><img border="0" src="http://1.bp.blogspot.com/-FruqLV_oUXw/UhRAI0dkt8I/AAAAAAAABVM/ZzEX0JSnXW8/s200/vehicle-dark-16x9.png" /></a></div>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0tag:blogger.com,1999:blog-4470168163688426003.post-76323640219386434492013-08-21T00:40:00.000-04:002013-08-21T00:42:37.496-04:00Rktcr: Now for sale<p><a href="http://tchow.com/games/rktcr/">Rktcr</a> is now for sale <a href="http://desura.com/games/rktcr">on Desura</a>. It's $5 now, and will be $10 if you wait too long. </p><div style="text-align:center"><img border="0" style="box-shadow:none;-webkit-box-shadow:none;" src="http://4.bp.blogspot.com/-7cdOZWGvn7Y/UhRDKnMKyII/AAAAAAAABWM/K_ZHPeBmwG0/s1600/rktcr0001.png" /></div><h2>Your TODO list:</h2><ol><li>Try the <a href="http://tchow.com/games/rktcr/#demo">Rktcr demo</a>. If you like it, proceed to (2), else goto (3).</li><li><a href="http://desura.com/games/rktcr">Buy Rktcr</a>.</li><li>Tell folks you think might like Rktcr about it.</li><li>Help me come up with things I should do if Rktcr sales reach various targets.</li></ol><p>In service of (4), let me say that I will change my hair/beard style if Rktcr sells more than 1024 copies. </p><p>Please leave more suggestions in the comments below, should you feel so inclined. </p>Jim McCannhttps://plus.google.com/106620557512272414686noreply@blogger.com0