{"id":592,"date":"2019-12-06T07:03:22","date_gmt":"2019-12-06T07:03:22","guid":{"rendered":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/?p=592"},"modified":"2019-12-11T20:55:25","modified_gmt":"2019-12-11T20:55:25","slug":"whats-in-a-beatmap","status":"publish","type":"post","link":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/2019\/12\/06\/whats-in-a-beatmap\/","title":{"rendered":"What&#8217;s in a Beatmap?"},"content":{"rendered":"\n<p>Beatmaps are a staple of many rhythm games, especially those that involve using the same mechanics to play multiple tracks or songs. A bunch of our prototypes used beatmaps (Beat\u2019Em, Gang Beasts, Chopin Beats, Laserfade, Kinectic) to different degrees.<\/p>\n\n\n\n<p>Here\u2019s the approach we took to coming up with beatmapping systems for our various games.<\/p>\n\n\n\n<p>First: what do your notes, cues, actions, etc. look like? What is the player\u2019s primary beat-related action? How many varieties of actions do they have?<\/p>\n\n\n\n<p>In <em>Guitar Hero<\/em>, these are the gems that fall down to the action bar. There are single notes, hold notes, and hammer-ons\/pull-offs.<\/p>\n\n\n\n<p>For the games in this project, most of our notes required the same type of input &#8212; a simple button press, or in VR, making contact with the note object by slicing it (<em>Chopin Beats<\/em>) or pushing it into a collider (<em>Kinectic<\/em>). However, all of our notes in <em>Kinectic<\/em> consist of a variety of positions that the note must be pushed into, so that had to be taken into consideration when deciding what functionalities our NoteData and NoteController classes needed to have.<\/p>\n\n\n\n<p>Next: how many <em>positions<\/em> do your notes occupy?<\/p>\n\n\n\n<p>Simpler rhythm games like <em>Guitar Hero<\/em> have a small, fixed number of note positions, often limited by controller input. However, games like <em>osu!<\/em> have notes that can start and end anywhere on the screen, storing note positions as XY coordinates.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/CKAEHmQnSFLbz7CoQP3XG2m9_uGkXxDLnzgAWwvNhK7j4HLjLO84QPLGGPPka2FaEM1qQqAuclU8fcyLvYkrMClmNN3_rqT-Zd9G5vZZANc2GoxPRZPS2y0ZriQChD5_6SfHHyD7\" alt=\"\"\/><\/figure>\n\n\n\n<p>When we were playing around with the idea of <em>Kinectic <\/em>having a grid of note positions surrounding the player on all 4 sides, it was key to solidify the naming convention of these positions before going forward. While we ended up settling with just 1 grid in front of the player, we came up with a naming system that would allow us to adjust the number of rows and columns in the grid.<\/p>\n\n\n\n<p>Finally: how do your game designers want to compose beatmaps? What is the most efficient way for them to compose beatmaps?<\/p>\n\n\n\n<p>This is something that most rhythm game players don\u2019t have a chance to see or experience, but an integral part of building a rhythm game. Most commercial games don\u2019t release their in-house beatmap making systems, but modders (and some indie game developers) often create their own solutions for custom beatmap-making that can be of inspiration.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/GF25czTH-9o3AzKM0dxHMUY0t6KWX2uIDAe7TULWRM8xxl-V6RWJGL_roZxiyZIvs4FnoN3xsznLOg8WMCMPTAYVp6QOSKc2y5KPVha48IuGJzoK_yfQ2-__NkSwuU-_SDYSf9-j\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/k5mXzpYX8Otvo85fPjzqfFbLMSxmHcFpjzCpImc8uxE87KZogxzrjfdjg3uurLJkLbrvPjgHx2ozJihJhZ9V96YvUlYzne10SzkZXgetjJidleXl_wwCP_Bthpvg5slB1W0MreqW\" alt=\"\"\/><\/figure>\n\n\n\n<p>These tend to have a timeline, representing the track length, along which the beatmap designer can place and snap cues to appropriate beats (or fractions of beats).<\/p>\n\n\n\n<p>We were on a tight timeline for this project, and the giant disparities in design between all our rhythm games meant that it was pretty much impossible for us to create a one-size-fits-all beatmap maker tool (though this would have saved us a lot of time!). Implementing a GUI for a scrubbable timeline was something we decided was not feasible, with such a small team where everyone wore multiple hats (both our programmers are also designers).<\/p>\n\n\n\n<p>Instead, we optimized where we could. When our games had a small variety of notes and positions (e.g. <em>Laserfade<\/em>, with 6 positions and only 2 possible note types, or <em>Chopin Beets<\/em>, with 2 positions and 3 possible note types), we used markers in FMOD on the music track itself for composing the beatmap. You can read more about this in our first programming post-mortem about syncing game events to music.<\/p>\n\n\n\n<p>We programmed the cue-spawning systems for these games to read the marker name (a predefined string, such as <em>L1 <\/em>or <em>R3<\/em>) and spawn the appropriate object, perfectly synced with the music.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/ZRfRlXL3pGbUgFQJMiWR17soaV9QMBaS4vqaK4aOQnpzu-XlLb8XMMvjO_2SHAzh9tMShVfkHsB8imuDue5Mk33RlLlpxOiRYtAELPR6r3yx71WBj7BkAVPmmg1YkRhVEUOuu2oS\" alt=\"\"\/><\/figure>\n\n\n\n<p>Games that require more complex choreography that is highly dependent on the music, especially VR games, may be best beatmapped \u201clive\u201d by tapping out inputs as the music plays. In this case, it may be best to devise a system that lets designers create beatmaps to a slowed-down version of the music track.<\/p>\n\n\n\n<p>One caveat is that designers can and will make mistakes when beatmapping live, no matter how slowed-down the track is. Using a live beatmapping system in conjunction with a timeline should allow designers to edit their inputs as they go.<\/p>\n\n\n\n<p>In the case of our game, <em>Kinectic<\/em>, we struggled to come up with a static beatmapping system due to the gesture-intensive nature of the game\u2019s inputs, and decided on making a VR beatmapping system instead. Our system was a matrix of collision boxes in front of the player that our beatmap designer activated by physically drawing lines between them using the Oculus Touch controllers.<\/p>\n\n\n\n<p>Because we had no time to implement a timeline, we decided on using CSVs to store beatmap data in a designer-friendly way, so that our non-programmer designers could easily edit beatmaps. Even with a timeline-based beatmapping system, having an editable file that can be used to make minor adjustments without having to fire up your beatmapping application.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/XkrJzz20SeDp3OnLCayXQZp_a7icUyt2erg2WV2G0DD4eyGkSU2iHjsscdwKFsFssm6u7p1fVt1BoB7F1Cnimy1E97WvrZSmvtawmXssfaLUduSpNRw28pmmwU3QI35NtYmX4vp1\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/nK8Rw85YgsUTZOCN3AGfFntfA38y8u9pzPKzxsYEGRc7w0e8RSquAsq-goXJan40lhH8CA9XbdT8kDeCYzk_UEE2nqcbBt3XICvkykWHYIhwmSpLzJwttwKEFQtIUsoGS9mTlTCs\" alt=\"\"\/><\/figure>\n\n\n\n<p>A good practice in Unity is to convert file data like CSVs into ScriptableObject assets, especially because these assets don\u2019t change at runtime. Extending Unity\u2019s editor classes can allow for a highly-customizable display of beatmap data.<\/p>\n\n\n\n<p>Having these things in mind when coming up with data structures and systems saved us a lot of time and effort when we were prototyping our 8 games. If you\u2019re trying to create a beatmap-based rhythm game too, hopefully this short article has given you some food for thought!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Beatmaps are a staple of many rhythm games, especially those that involve using the same mechanics to play multiple tracks or songs. A bunch of our prototypes used beatmaps (Beat\u2019Em, Gang Beasts, Chopin Beats, Laserfade, Kinectic) to different degrees. Here\u2019s [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-592","post","type-post","status-publish","format-standard","hentry","category-analysis","col-lg-4 col-md-6"],"_links":{"self":[{"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/posts\/592"}],"collection":[{"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/comments?post=592"}],"version-history":[{"count":1,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/posts\/592\/revisions"}],"predecessor-version":[{"id":593,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/posts\/592\/revisions\/593"}],"wp:attachment":[{"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/media?parent=592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/categories?post=592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/projects-old.etc.cmu.edu\/jam-session\/index.php\/wp-json\/wp\/v2\/tags?post=592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}