{"id":21172,"date":"2013-09-25T09:14:13","date_gmt":"2013-09-25T14:14:13","guid":{"rendered":"http:\/\/www.shamusyoung.com\/twentysidedtale\/?p=21172"},"modified":"2015-07-01T04:46:47","modified_gmt":"2015-07-01T09:46:47","slug":"project-good-robot-18-more-robots","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=21172","title":{"rendered":"Project Good Robot 18: More Robots"},"content":{"rendered":"<p>A small announcement before I get to the post itself: Last entry I mentioned I needed music. I didn&#8217;t expect that multiple people would be offering to compose original music for my game for free.  I&#8217;ve been quiet about these offers for help so far because I didn&#8217;t know how to respond, but then composer Fawstoar made <a href=\"http:\/\/www.youtube.com\/watch?v=iMSaZvXUsEk\">this track<\/a> and I couldn&#8217;t say no.<\/p>\n<p>But here&#8217;s the thing:  I&#8217;m really nervous about inviting people to make tracks for the game, because I&#8217;m the absolute <em>worst<\/em> sort of person to make music for. My tastes are lowbrow, but I&#8217;m also incredibly picky and I know nothing whatsoever about music.  I&#8217;m sure everyone has run into the classic <a href=\"http:\/\/clientsfromhell.net\/\">Clients from Hell<\/a> stories, where a client keeps asking for changes because they do know what they don&#8217;t want but they don&#8217;t know what they do want and in any case they lack the basic vocabulary to even express their preferences.  So you wind up with a client repeatedly asking you to change the color scheme of the website and it isn&#8217;t until your sixth revision that you discover the color isn&#8217;t the problem, it&#8217;s that they wanted the buttons to look more &#8220;glossy&#8221; like [huge boring corporate site that&#8217;s looking kind of dated] and they&#8217;re actually colorblind and couldn&#8217;t even detect most of the changes you were making. <\/p>\n<p>That client? That irritating jackass? That&#8217;s me. You don&#8217;t want to make music for me. I&#8217;m an idiot. I want a very specific kind of inoffensive electronic music, I lack the knowledge and language to explain what it is, and I don&#8217;t want to pay for anything. Who would want to deal with <em>that<\/em>?<\/p>\n<p>While I&#8217;m wise enough to see that making music for my game would be bad for you, I&#8217;m also selfish enough that I&#8217;m willing to offer the chance if you want to try. But rather than asking someone to go out and make music, I&#8217;ll just leave the door open for submissions. If you think you have something that fits, just leave a comment with a link to the track on Soundcloud or Youtube or whatever and I&#8217;ll give it a listen.  If I like it, I&#8217;ll put it in the game. If I don&#8217;t, I will probably avoid saying why because I don&#8217;t want you to spend two days re-working it only to have me still not like it because I gave you bad advice.<\/p>\n<p>Obviously I&#8217;m not looking for exclusive rights. I just want tracks that I&#8217;m allowed to use in my game. And if you don&#8217;t want to do hours of work trying to please an ignorant slob who might not finish the stupid videogame anyway? I don&#8217;t blame you.<\/p>\n<p>The mood I&#8217;m going for is&#8230; uh. I guess pretty much the original Descent:<\/p>\n<p><table class='nomargin' cellspacing='0' width='100%' cellpadding='0' align='center' border='0'><tr><td><iframe loading=\"lazy\" width=\"1024\" height=\"576\" src=\"https:\/\/www.youtube.com\/embed\/keS0Hts2LpQ\" frameborder=\"0\" allowfullscreen class=\"embed\"><\/iframe><br\/><small><a href='http:\/\/www.youtube.com\/watch?v=keS0Hts2LpQ'>Link (YouTube)<\/a><\/small><\/td><\/tr><\/table><\/p>\n<p>Except maybe not quite so&#8230; 1994 MIDI-ish? (See what I mean about me being a horrible and difficult client?) Perhaps the <a href=\"http:\/\/www.youtube.com\/watch?v=9IISjIMpepo\">Unreal soundtrack<\/a> would be a better example. Tracks don&#8217;t need to be epic long compositions. In testing, levels currently only take about five to ten minutes, so a two or three minute track that&#8217;s looping-friendly should do just fine.  Most players won&#8217;t even notice the repetition in that timeframe. <\/p>\n<p>Some of you have already linked to your work on Soundcloud \/ Youtube \/ Jamendo.  I&#8217;ve listened, and I&#8217;m considering some of them. We&#8217;ll see.<\/p>\n<p>Anyway, let&#8217;s talk about the game:<\/p>\n<p><!--more--><br \/>\n<table width='600'  cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/gr18_screen4.jpg' class='insetimage' width='600' alt='This problem would be easier to solve if I wasn&#8217;t out of missiles myself.' title='This problem would be easier to solve if I wasn&#8217;t out of missiles myself.'\/><\/td><\/tr><\/table><\/p>\n<p>You know what&#8217;s fun in this game? Dodging missiles. Maybe it&#8217;s just me. So far only two of my seven playtesters (my daughter Rachel and myself) seem to get caught up in missile-dodging. <\/p>\n<p>How it works is this:  A robot shoots a homing missile at you.  Your lasers are busy elsewhere, so instead of shooting down the missile you cut to the side at the last second and the missile zips by.  You feel pretty good until you realize it&#8217;s not going to give up that easily. It loops around and while that&#8217;s happening another missile is already on the way. The turning radius of a missile is too large to hit you like this, so there&#8217;s now a missile circling you in each direction and also the robot is still shooting so you&#8217;ve got another one on the way.  It seemed like a pretty slick move the first time you dodged one, but now you&#8217;re kind of pinned in this circle until you can shoot them down, which makes it hard to avoid all this incoming laser fire. <\/p>\n<p>So dodging missiles is a very temporary solution to the problem, and in fact can make things worse if you let it get out of hand. But it&#8217;s fun.  <\/p>\n<p>The missile flight patterns are interesting enough that I&#8217;m thinking it would be good to have an enemy that moves this way. This would mean making one that moves forward constantly and must turn itself around to change movement direction.  So let&#8217;s do that. I think I&#8217;ll call these new enemies &#8220;flyers&#8221;, since they fly around you all the time.<\/p>\n<p><table width='600'  cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/gr18_screen2.jpg' class='insetimage' width='600' alt='I&#8217;ll confuse him by dodging directly into his lasers!' title='I&#8217;ll confuse him by dodging directly into his lasers!'\/><\/td><\/tr><\/table><\/p>\n<p>It&#8217;s kind of boring to have them just fly loops around you, and it also makes them kind of predictable. But after some experimenting I find a nice simple system for keeping their movements interesting.  Instead of orbiting the player, they orbit a point a slight distance from the player.  If the robot is on your left, it tries to fly around a spot just above you. If it&#8217;s on your right, it goes for a spot just below you.  When it shoots, it reverses these.  <\/p>\n<p>This is complete chaos. These rules are dead simple, but this thing is hard to hit <em>and<\/em> hard to dodge, which is a surprising combination. Just about the point where I get the little bastard lined up, it&#8217;s ramming into me and I have to juke to avoid getting&#8230; uh&#8230; bitten? I dunno.  Whatever we&#8217;re calling these melee attacks. <\/p>\n<p>The other thing that makes this fun to fight is that when I&#8217;m in a tight passage, it spends about half its time inside the walls.  I haven&#8217;t written any collision detection for it yet, so instead of slamming into walls it just passes through like Casper. Then I spend a few panicked seconds waving my laser around, wondering where it will pop out. <\/p>\n<p><table width='600'  cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/gr18_screen3.jpg' class='insetimage' width='600' alt='Where is Kevin Bacon when you need him?' title='Where is Kevin Bacon when you need him?'\/><\/td><\/tr><\/table><\/p>\n<p>This behavior is interesting enough that I think it needs to be a feature. So I add some effects to make it look like this thing is boring through walls. When it collides with level geometry, it halves its speed, gives off a scattering of rock particles, and begins emitting a rumbling sound.  There&#8217;s another sound and particle burst when it exits again.  <\/p>\n<p>Great. So I&#8217;ve come up with another new and interesting enemy type. Which tunnels through the ground. And which I&#8217;ve named &#8220;Flyer&#8221;. The name is extra stupid, since most of the other robots also fly. <\/p>\n<p>I spend a few minutes re-naming this and everything is great.  But speaking of naming problems&#8230;<\/p>\n<p>Originally you were going to buy upgrades in this game.  Monsters would drop coins, and when you reached a shop you would pay for upgrades. Except, I don&#8217;t like the feel of this.  If the player happened to miss the shop (easy to do in these tunnels) then they might go for a long time with a bunch of money they couldn&#8217;t spend.  Also, I wanted to give out lots of upgrades at first and gradually space them out later on. How do I do that? Give <em>more<\/em> money in the easy early levels and less when the game is hard? That would just incentivize the worst sort of grinding. I could have the costs ramp up over time, but that goes against the type of upgrade system I&#8217;m trying to make. <\/p>\n<p>Then I realized that what I wanted was a leveling system. So I replaced the store system with a level system.  Except&#8230;<\/p>\n<p>I already have a &#8220;level&#8221; system.  In level.cpp, I procedurally generate gameplay areas called &#8220;levels&#8221;.  It took me a couple of days to even notice I&#8217;d made this blunder.  When I did, I figured it was no big deal.  I&#8217;ll just make sure to name stuff like &#8220;character_level&#8221; to differentiate from &#8220;place level&#8221;. Surely I can keep the two level systems straight, right?<\/p>\n<p>Well, no. A few days later I got myself turned around and started plugging the wrong variable into the wrong system.  I was messing with xp per level, which I thought was how much xp it takes to gain a level, but was actually how much xp was available in a specific area of the game. Then later I thought the &#8220;max level&#8221; variable in the save file was how far something(?) had leveled up, but it was really the highest numbered checkpoint save the player had reached. And then there are skill levels, which is how far individual skills have been upgraded. Basically this <a href=\"http:\/\/www.giantitp.com\/comics\/oots0012.html\">Order of the Stick<\/a> has become a running gag all through my code.  <\/p>\n<p>For a while I get by with making the names more descriptive.  I&#8217;ll call something &#8220;character_level&#8221; instead of &#8220;level&#8221;. But there are still situations where meanings can be ambiguous and turning variables into sentences is a poor solution to that. This is only going to get worse. If I&#8217;m getting confused when I&#8217;m actively working on the project, then this is very bad.  If I had to step away from the project for a few days due to sickness or other obligations, then by the time I got back I would have forgotten which level was which and it would be madness. <\/p>\n<p>So over the course of two honkin&#8217; hours I painstakingly rename everything to do with gamespace geometry from &#8220;level&#8221; to &#8220;map&#8221;.  It probably would have been faster to rename the other sort of level, but I have no idea what else it could be called that I&#8217;d remember and that wouldn&#8217;t just cause more confusion elsewhere.<\/p>\n<p>I suppose it would help if I had better refactoring tools. Or if I had any at all. When I worked with the <a href=\"?p=15758\">Qt platform<\/a>, the dev environment had a built-in feature that would let you rename a variable. It was smart enough to understand the difference between the variable you&#8217;re renaming, and another variable elsewhere that happens to have the same name. (Which is probably why you&#8217;re renaming this one.) It&#8217;s smart enough to not mess with stuff inside comments, or rename partial matches.<\/p>\n<p><table width='600'  cellpadding='0' cellspacing='0' border='0' align='center'><tr><td><img src='https:\/\/www.shamusyoung.com\/twentysidedtale\/images\/gr18_code.jpg' class='insetimage' width='600' alt='Maybe I should have made you sign an NDA before I let you see this code.' title='Maybe I should have made you sign an NDA before I let you see this code.'\/><\/td><\/tr><\/table><\/p>\n<p>But I&#8217;m using Microsoft Dev Studio, and for some unfathomable reason they don&#8217;t have a tool like that.  The environment is actually aware of variables, but it doesn&#8217;t use that knowledge when renaming. All you get is stupid Find &#038; Replace, which is incredibly dangerous. One bad command can make a complete mess of the code, or rename things in ways you don&#8217;t realize until much later. And if you&#8217;re trying to rename something because it&#8217;s too similar to something else, then Find &#038; Replace is like using a Flamethrower to test your smoke detector: You&#8217;re likely to cause a catastrophic version of the problem you&#8217;re trying to avoid. <\/p>\n<p>(To be fair, maybe the full version of Visual Studio has a proper rename tool.  I&#8217;m using the Hippie Freeloader Edition&trade; right now.  Then again, I had the pro edition of an old (1998) version at my old job, and it didn&#8217;t have smart renaming either.) <\/p>\n<p>It sucks to lose a couple of hours like that, but this sort of thing happens. As a program grows it gets harder to keep the whole thing in your head. If you&#8217;re like most people you probably gravitate towards certain words and those habits find their way into code. And if you&#8217;re like me then you&#8217;re probably getting on in years and finding it harder to remember what you were thinking when you wrote something.<\/p>\n<p>So those are the most interesting problems last week. I have to say this is going amazingly well. I haven&#8217;t lost a day to some intractable tech problem.  Or had to deal with ongoing crash bugs. I haven&#8217;t been plagued by performance problems. Maybe this is because &#8220;2D is easy&#8221;, or maybe I&#8217;m just really at the top of my game, but it feels good when a project flows like this. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>A small announcement before I get to the post itself: Last entry I mentioned I needed music. I didn&#8217;t expect that multiple people would be offering to compose original music for my game for free. I&#8217;ve been quiet about these offers for help so far because I didn&#8217;t know how to respond, but then composer [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[498],"tags":[],"class_list":["post-21172","post","type-post","status-publish","format-standard","hentry","category-good-robot"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/21172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=21172"}],"version-history":[{"count":0,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/21172\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=21172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=21172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=21172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}