{"author_name":"DDRKirby(ISQ)","cat":"LD #33","comments":[{"author_name":"GhostBomb","time":"September 13, 2015 1:12 am","epoch":1442124720,"text":"I&#8217;d like to see a video of you beating the expert songs with 5 stars just to confirm that it&#8217;s possible.","spam":"N"},{"author_name":"","time":"December 9, 2015 1:20 am","epoch":1449642000,"text":"Well, I can&#8217;t, but that doesn&#8217;t mean it&#8217;s not possible:","spam":"N"}],"epoch":1442117700,"likes":13,"metadata":{"p_key":"2428","p_author":"DDRKirby(ISQ)","p_authorkey":"7285","p_urlkey":"48216","p_title":"Melody Muncher Post-Mortem","p_cat":"LD #33","p_event":"LD33","p_time":"1442117700","p_likes":"13","p_comments":"2","p_status":"UPD5","us_key":"7285","us_name":"DDRKirby(ISQ)","us_username":"ddrkirbyisq","event_start":"1440115200","event_key":"29","event_name":"LD33"},"text":"<p>Hi there! \u00a0DDRKirby(ISQ) here with my =10th= LD entry (wow!), Melody Muncher!<\/p>\n <p><a href=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/21.png\"><img class=\"aligncenter size-large wp-image-501170\" src=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/21-550x330.png\" alt=\"2\" width=\"550\" height=\"330\" srcset=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/21-300x180.png 300w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/21-550x330.png 550w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/21.png 1000w\" sizes=\"(max-width: 550px) 100vw, 550px\" \/><\/a><\/p>\n <p>Link to play and rate:\u00a0<a href=\"http:\/\/ludumdare.com\/compo\/ludum-dare-33\/?action=preview&amp;uid=7285\">http:\/\/ludumdare.com\/compo\/ludum-dare-33\/?action=preview&amp;uid=7285<\/a><\/p>\n <p>This one was a blast to make, and I ended up working for 2 weeks to make the Post Compo version (out now!), adding a new mechanic, animated backgrounds for each level, more songs, 3 separate difficulties, and more!<\/p>\n <p>When the theme was announced this time as &#8220;You Are the Monster&#8221; I was actually quite disappointed, just due to the fact that it was so similar to &#8220;You Are the Villain&#8221;! \u00a0I mean come on guys, really? \u00a0But now that I think of it, You Are the Villain was EIGHT LDs ago, so I guess I can&#8217;t fault people too much for it. \u00a0I wonder if anyone decided to redo the same game concept that they did for LD25? \u00a0It would be an interesting challenge, just to see how far your game jam skills have come over the past years&#8230;<\/p>\n <p>Anyways, despite my initial dislike for the theme, my idea and game came together really smoothly this time; I can&#8217;t even remember running into any hiccups at all! \u00a0As always, let&#8217;s go over what went well and what didn&#8217;t go well.<\/p>\n <p>&nbsp;<\/p>\n <p><span style=\"text-decoration: underline\"><strong>What went well:<\/strong><\/span><\/p>\n <p><strong>Avoiding other commitments during LD weekend<br \/>\n <\/strong>Almost every other LD I&#8217;ve done, I&#8217;ve had =something= else to attend to over the course of the jam, usually on Friday night. \u00a0Usually I tell myself that it&#8217;s fine and that I can just try to brainstorm in my head while that happens, but to be honest, that never quite works out and it&#8217;s basically like I\u00a0start off behind by 4 hours already. \u00a0This time I decided that I really was just going to dedicate the whole weekend to LD and besides some driving here and there and dealing with meals (gotta eat!), I was just heads down working the whole time, which was GREAT! \u00a0An exhausting weekend, for sure, but I don&#8217;t think there&#8217;s any way around that. \u00a0For Sunday, after breakfast and running a quick errand in the morning, I pretty much worked straight through the entire day until the deadline&#8230;I stopped twice for the bathroom, once for refilling water, and once for a massive yawn\/stretch&#8230;that&#8217;s it. \u00a0Hahaha, you other LDers will know what I&#8217;m talking about&#8230;Sunday is usually that day when it&#8217;s like &#8220;omg I have 5 hours left and I still have to add in 2 more enemy types, also my game has no menu, title, or tutorial and I haven&#8217;t tested the difficulty at all AHHHHHH&#8221;.<\/p>\n <p><a href=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/32.png\"><img class=\"aligncenter size-large wp-image-501182\" src=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/32-550x330.png\" alt=\"3\" width=\"550\" height=\"330\" srcset=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/32-300x180.png 300w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/32-550x330.png 550w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/32.png 1000w\" sizes=\"(max-width: 550px) 100vw, 550px\" \/><\/a><\/p>\n <p><strong>Game concept and execution<\/strong><br \/>\n As mentioned earlier, everything came together really smoothly for Melody Muncher, without a hitch, really! \u00a0I spent Friday night doing my usual brainstorming routine, and considered plenty of other possibilities, but the idea of having the piranha plant munching guys as a rhythm game occurred to me pretty early on, and it clearly had the most potential while also playing to my strengths, so I went for it. \u00a0Huge success!<\/p>\n <p><strong>Level data layout<br \/>\n <\/strong>One of the reasons I was able to cram in six (!) full songs to the 48hr version of Melody Muncher was because I made sure the levels were really easy to program in. \u00a0Unfortunately this was NOT the case for my previous game of this genre, <a href=\"http:\/\/ludumdare.com\/compo\/ludum-dare-29\/?action=preview&amp;uid=7285\">Ripple Runner<\/a>.<\/p>\n <p>Here&#8217;s what a level definition looks like in Ripple Runner:<\/p>\n <pre>\/\/ Section 1\n addPlatform(startTime + -10.0 \/ bps, startTime + 36.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + -10.0 \/ bps, startTime + 36.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 37.0 \/ bps, startTime + 44.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 37.0 \/ bps, startTime + 44.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 45.0 \/ bps, startTime + 52.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 45.0 \/ bps, startTime + 52.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 53.0 \/ bps, startTime + 60.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 53.0 \/ bps, startTime + 60.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 61.0 \/ bps, startTime + 62.0 \/ bps, -45, timingWindow, level);\n addPlatform(startTime + 61.0 \/ bps, startTime + 62.0 \/ bps, 45, timingWindow, level);\n addPlatform(startTime + 63.0 \/ bps, startTime + 80.0 \/ bps, -40, timingWindow, level, true);\n addPlatform(startTime + 63.0 \/ bps, startTime + 80.0 \/ bps, 40, timingWindow, level, true);\n GameWorld.world().add(new Checkpoint(startTime + 64.0 \/ bps, -40));\n ...\n \/\/ Section 2\n addPlatform(startTime + 80.0 \/ bps, startTime + 100.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 80.0 \/ bps, startTime + 108.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 108.0 \/ bps, startTime + 116.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 116.0 \/ bps, startTime + 120.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 120.0 \/ bps, startTime + 124.0 \/ bps, -40, timingWindow, level);\n addPlatform(startTime + 124.0 \/ bps, startTime + 126.0 \/ bps, 40, timingWindow, level);\n addPlatform(startTime + 126.0 \/ bps, startTime + 128.0 \/ bps, -40, timingWindow, level, true);\n ...\n ...\n ...<\/pre>\n <p>And so on and so forth. \u00a0And that&#8217;s only the =first half= of the EASIEST level. \u00a0Yuck! \u00a0Unfortunately I was super duper hacky while coding up Ripple Runner so the way that I constructed the levels was actually just by placing each platform individually. \u00a0This involved tons of hacks, especially trying to deal with assymmetrical timing windows which varied according to which kind of obstacle you were using (spikes, rippling, jumping), and a bug that prevented me from creating single platforms that were too long&#8230;.etc etc.<\/p>\n <p>Thankfully I didn&#8217;t repeat the same mistake this time. \u00a0Here&#8217;s what a level looks like in Melody Muncher:<\/p>\n <pre>result.SfxName = \"sfx\/level3\";\n result.BeatDivision = 2;\n result.BeatPixelLength = 80;\n result.Left =\n \"........ ........ ........ ........\" +<\/pre>\n <pre>\"1.....1. 1....... 1....... 1...1...\" + \"1....... 1....... 1.....2. 1...1...\" +\n \"1.1..... 1...1.1. 1....... ........\" + \"1...1.1. 1.1..... 1....... ........\" +\n \"1.1..... 1...1.1. 1.1.2.1. ........\" + \"1...1.1. 1.1..... ........ 1.1.2.1.\" +\n \"1....... 1....... 1.....1. 1...1...\" + \"1.....2. 1....... 1....... 1...1...\" +<\/pre>\n <pre>\"........\";\n result.Right =\n \"........ ........ ........ ........\" +<\/pre>\n <pre>\"1....... 1....... 1.....1. 1...1...\" + \"1.....2. 1....... 1....... 1...1...\" +\n \"1...1.1. 1.1..... 1....... ........\" + \"1.1..... 1...1.1. 1....... ........\" +\n \"1...1.1. 1.1..... ........ 1.1.2.1.\" + \"1.1..... 1...1.1. 1.1.2.1. ........\" +\n \"1.....1. 1....... 1....... 1...1...\" + \"1....... 1....... 1.....2. 1...1...\" +<\/pre>\n <pre>\"........\";<\/pre>\n <p>Much better! \u00a0Here I&#8217;m using &#8220;1&#8221; to indicate a green enemy, &#8220;2&#8221; for a red enemy, and &#8220;3&#8221; for blue enemies (which don&#8217;t appear in this particular level). \u00a0I ended up using &#8220;[&#8221; and &#8220;]&#8221; to denote the yellow centipede enemies in the post-compo version. \u00a0The periods just indicate points where there are no enemies, and spaces get automatically ignored. \u00a0It&#8217;s still perhaps not 100% ideal as I still had to build up separate strings for the left and right sides of the screen, but overall inputting notes for songs went pretty quickly.<\/p>\n <p><strong>Coding it the Right Way<br \/>\n <\/strong>So, again, for Ripple Runner I used a bunch of stupid hacky coding, and as a result, even though your X position in Ripple Runner is locked to the position of the song (good!), your jump height and y position is not (bad!)&#8211;it&#8217;s actually just normal platformer gravity. \u00a0This led to some pretty clumsy manual hacking about to get the gravity to be correct for each level (it needs to be adjusted for each BPM setting!), and in general just led to sad times within the code. \u00a0The end result still ended up just fine, but&#8230;<\/p>\n <p>When it came to program Melody Muncher, I had learned my lesson, so I made sure to do everything right. \u00a0The position of all of the enemies is dictated solely by the position of the music, and there are NO collision boxes or movement physics or anything! \u00a0Each enemy knows what beat it should be hit on,\u00a0and the enemies on either side are kept in an Array, sorted by order of arrival. \u00a0When you press left or right, we run through the first part of the Array looking for enemies whose beat is within the defined timing window&#8211;no collisions or any other nonsense needed! \u00a0Very clean, very sensible, and the code was much better and simpler as a result.<\/p>\n <p><a href=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/41.png\"><img class=\"aligncenter size-large wp-image-501172\" src=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/41-550x330.png\" alt=\"4\" width=\"550\" height=\"330\" srcset=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/41-300x180.png 300w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/41-550x330.png 550w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/41.png 1000w\" sizes=\"(max-width: 550px) 100vw, 550px\" \/><\/a><\/p>\n <p><strong>Post-Compo Version<br \/>\n <\/strong>This might not technically count as something that &#8220;went well for LD&#8221;, but this was the most fun I&#8217;ve ever had working on a Post-Compo version of a game I&#8217;ve made. \u00a0Probably because of the above two factors, and also because I knew I had something with a lot of potential. \u00a0Making new songs and mechanics was a blast, and even though it took a lot of work to add all of the new features in the Post-Compo version, I&#8217;m super happy with how it turned out, and I believe this is my most polished game ever as a result.<\/p>\n <p>&nbsp;<\/p>\n <p><span style=\"text-decoration: underline\"><strong>What didn&#8217;t go so well:<\/strong><\/span><\/p>\n <p><strong>Input Delay and Lag Calibration<\/strong><br \/>\n Okay&#8230;so this was mostly a stupid mistake. \u00a0So one of the mechanics in the game is that after a few levels, enemies can come at you simultaneously from both sides, so you have to press Left and Right at the same time to do a split munch. \u00a0Simple enough, right?<\/p>\n <p>Well, on the coding side, I implemented this by having a separate animation &#8212; one where Ms. Melody has two heads that are each attacking. \u00a0(As it turns out, while working on the Post-Compo version I had to redo this and just implement each head separately to allow for the yellow long centipede enemies to work) \u00a0I then also decided that because people probably weren&#8217;t always going to hit left and right at exactly the same time, what I would do is this:<\/p>\n <p>When you first hit left or right, the plant transitions into a &#8220;getting ready to attack&#8221; state (with a different animation frame) and waits for a frame or two, during which you have the opportunity to input the other direction. \u00a0Once the frame or two is up, the attack actually happens. \u00a0So this was good because even if you hit left on frame #1 and right on frame #2, you still get the split munch on both sides.<\/p>\n <p>The problem is that by doing this, I essentially delayed every input (as well as the resulting &#8220;munch&#8221; sound) by something like 17 or 33ms. \u00a0Now, that may not seem like much, but in a rhythm game where your actions need to be really tightly synced, you can really notice, and people did. \u00a0Add that to the fact that my default lag calibration for Flash builds was slightly off (I had to shift it by maybe ~50ms compared to native builds) and people definitely felt that their inputs were delayed. \u00a0Now, part of this was that I simply didn&#8217;t have enough time to program in a robust and user-friendly lag calibration setting (it&#8217;s much better in the post-compo version!), but most of this was just my own fault for adding additional input delay unnecessarily.<\/p>\n <p>The good news is that the post-compo version fixes this entirely, and if you compare the two the post-compo version should feel MUCH better.<\/p>\n <p><strong>Missing was too punishing<\/strong><br \/>\n In the original 48hr version of the game, if you try to attack when no enemy is on the corresponding side, Ms. Melody does this ugly faceplant animation which leaves you stunned for a half beat or so. \u00a0This was designed intentionally as a means of punishing you for trying to attack when there was no enemy, as well as to eliminate the cheesy strategy of just trying to munch on both sides on every single eighth-note beat. \u00a0If you didn&#8217;t have the recovery animation, you&#8217;d just be able to do that and get a perfect score, which was obviously no good. \u00a0I had been trying to think of various ways to solve that issue, and after trying it, this seemed like a clean solution, as well as making it very unrewarding to miss notes, which is what I wanted &#8212; it should feel good when you hit enemies, and bad when you miss enemies.<\/p>\n <p>Well, the problem is that players don&#8217;t like feeling bad. \u00a0One of the complaints that I got was that the recovery time for missing was too long and it led to people feeling like the game was &#8220;unfair&#8221; (ugh, loaded term). \u00a0Now, if you&#8217;re used to rhythm games, you probably didn&#8217;t mind this as much, but if you&#8217;re not a rhythm gamer, what happens is that you miss one enemy, then because of that your input for the second enemy doesn&#8217;t register (since you&#8217;re still in recovery), which throws you off and then you end up missing again &#8230;&#8230;, in the end that&#8217;s a situation that just doesn&#8217;t really feel good. \u00a0So lesson learned &#8212; reward your players for succeeding, but don&#8217;t punish them for failing.<\/p>\n <p>The solution in the post-compo version was to eliminate the recovery delay and just add in a proper scoring system that adds points to your score based on your current chain, a la Guitar Hero. \u00a0Now I no longer need the recovery delay because if you try to use the strategy where you attack both sides on every eighth note, you&#8217;ll keep on breaking your chain over and over again, leading to a poor score. \u00a0Problem solved! \u00a0But unfortunately, I just didn&#8217;t have time to get the more fancy scoring system and everything done in the 48hr version.<\/p>\n <p><strong>No Shovel Knight<br \/>\n <\/strong>Okay, so this wasn&#8217;t really that big of a deal, but when I was drawing up the graphic for the red enemies I knew I wanted it to be something big, beefy, and blocky, so I went with an armored knight. \u00a0Since it was a knight, I decided to give it a sword. \u00a0I even referenced some Shovel Knight images as I was drawing it up&#8230;.but for SOME reason I missed the golden opportunity to just have my Red Knights carry shovels and be &#8220;shovel knights&#8221;. \u00a0Which would have made perfect sense (they&#8217;re trying to dig up Ms. Melody), AND would have been a great callout to a great game. \u00a0Biggest missed opportunity everrrrrr =(<\/p>\n <p><strong>48 Hours!!!!<\/strong><br \/>\n Alright, I guess this isn&#8217;t really something that &#8220;went wrong&#8221;, but it still amazes me every time how quickly the 48 hours goes by, despite you wanting to cram in more and more features. \u00a0&#8220;If only I had 1 extra hour!!!&#8221; \u00a0This was apparent this time around as well; the submitted version of my 48hr entry was missing some key components that I really really wanted to get in, but I just. did. not. have. enough. time.<\/p>\n <p>Specifically, better lag calibration was one item high-up on the wishlist that I didn&#8217;t end up getting to squeeze in until later. \u00a0It wouldn&#8217;t have taken long, either!<\/p>\n <p>And, changing backgrounds was another real big item. \u00a0I had a hue shifting effect that I used in Ripple Runner which worked fabulously, and I really wanted to do the same thing in Melody Muncher, because without it the backgrounds feel very static, especially when the music is very energetic and has these big builds and climaxes. \u00a0Of course, it turns out that because I&#8217;m now working in Haxe and Haxepunk, I can&#8217;t just use punk.fx (flashpunk) to do an easy hue shift; in fact I still don&#8217;t know of any good way to do hue shifting in Haxe\/Haxepunk without digging into low-level RGB code yourself. =( \u00a0The silver lining on that cloud is that because I wasn&#8217;t able to do easy hue shifting, I ended up making much more intricate and involved animated background effects for the post-compo version, so it all works out. <img src=\"http:\/\/ludumdare.com\/compo\/wp-includes\/images\/smilies\/simple-smile.png\" alt=\":)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n <p><a href=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/13.png\"><img class=\"aligncenter size-large wp-image-501169\" src=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/13-550x330.png\" alt=\"1\" width=\"550\" height=\"330\" srcset=\"http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/13-300x180.png 300w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/13-550x330.png 550w, http:\/\/ludumdare.com\/compo\/wp-content\/uploads\/2015\/09\/13.png 1000w\" sizes=\"(max-width: 550px) 100vw, 550px\" \/><\/a><\/p>\n <p>&nbsp;<\/p>\n <p>And that wraps up another post-mortem! \u00a0Results will be in very soon&#8211;good luck to everybody and remember, the real prizes are your games, not your ratings! \u00a0Be sure to take your scores with\u00a0some salt; sometimes you get scores that don&#8217;t quite make that much sense.<\/p>\n <p>Thanks for taking the time to read about <a href=\"http:\/\/ludumdare.com\/compo\/ludum-dare-33\/?action=preview&amp;uid=7285\">Melody Muncher<\/a>! \u00a0Hope you enjoyed it as much as I did! <img src=\"http:\/\/ludumdare.com\/compo\/wp-includes\/images\/smilies\/simple-smile.png\" alt=\":)\" class=\"wp-smiley\" style=\"height: 1em; max-height: 1em;\" \/><\/p>\n \n <p>Tags: <a href=\"http:\/\/ludumdare.com\/compo\/tag\/haxe\/\" rel=\"tag\">haXe<\/a>, <a href=\"http:\/\/ludumdare.com\/compo\/tag\/ld33\/\" rel=\"tag\">LD33<\/a>, <a href=\"http:\/\/ludumdare.com\/compo\/tag\/postmortem\/\" rel=\"tag\">postmortem<\/a><\/p>","time":"September 12th, 2015 11:15 pm","title":"Melody Muncher Post-Mortem"}