<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Get Info: #foretrack</title>
    <description>Posts tagged “foretrack” — Blog of independent game and app developer Matt Sephton. Featuring vintage Macintosh, game development, digital artwork, Japanese esoterica, video game reviews, hacks and tips, and much more.</description>
    <link>https://blog.gingerbeardman.com/tag/foretrack/</link>
    <atom:link href="https://blog.gingerbeardman.com/tag/foretrack/index.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 06 Jul 2026 14:37:40 +0000</pubDate>
    <lastBuildDate>Mon, 06 Jul 2026 14:37:40 +0000</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>

    
      
        <item>
          <title>A year in the life of a Playdate game developer</title>
          <description>&lt;p&gt;This week sees the &lt;a href=&quot;https://play.date/games/tags/on-sale&quot;&gt;first Anniversary Sale of Catalog, the official store for Playdate games&lt;/a&gt;. This means it’s almost the anniversary of &lt;a href=&quot;/2023/04/13/sparrow-solitaire-for-playdate/&quot;&gt;the release Sparrow Solitaire&lt;/a&gt;, which was the first Playdate work I did in 2023 after taking an enforced break.&lt;/p&gt;

&lt;p&gt;So I thought it would be interesting to look back and take stock of the last year of me making stuff for Playdate. What did I finish? What did I abandon? What is still to come?&lt;/p&gt;

&lt;p&gt;After Sparrow Solitaire (a huge game that took around a year of development time split between myself and Mac Vogelsang), it took me a few months to figure out the right sort of size and scope that would allow me to make a game every month or two, whilst minimising the risk of not selling enough. By September I was well and truly &lt;em&gt;in the zone&lt;/em&gt; and &lt;a href=&quot;/2023/11/21/yoyozo-how-i-made-a-playdate-game-in-39kb/&quot;&gt;created YOYOZO&lt;/a&gt; which went on to receive a commendation from Ars Technica as one of the &lt;a href=&quot;https://arstechnica.com/gaming/2023/12/ars-technicas-best-video-games-of-2023/7&quot;&gt;“Best Games of 2023”&lt;/a&gt;. And at the &lt;a href=&quot;https://play.date/games/community-awards-2023/&quot;&gt;2023 Playdate Community Awards&lt;/a&gt;, presented on 8th March 2024, Sparrow Solitaire won &lt;em&gt;Best Puzzle Game&lt;/em&gt; and YOYOZO won &lt;em&gt;Best Arcade Game&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Somebody asked me if this is my full-time job? My answer is: yes, this is my only job and I do it as often as I’m able. It’s certainly more complicated, due to various life stuff, but that’s the gist of things. Over the last twelve months, I would say I’ve been productive for around half my time.&lt;/p&gt;

&lt;p&gt;Recently I saw somebody say &lt;a href=&quot;https://twitter.com/indieretropod/status/1764443576597946593&quot;&gt;“Be careful with scope and look what you can do in a year!”&lt;/a&gt;, about the wonderful &lt;a href=&quot;https://twitter.com/johanpeitz&quot;&gt;Johan Peitz&lt;/a&gt;, and I think that addage can also be applied to my output this year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; 22 projects, 10 of which were released, and 5 are still to come. I’m pretty happy with that!&lt;/p&gt;

&lt;p&gt;I also managed to squeeze in a couple of non-Playdate projects: my first real Love2D game &lt;a href=&quot;https://gingerbeardman.itch.io/portrait-curling&quot;&gt;Portrait Curling&lt;/a&gt;, modifications to vintage pixel art app &lt;a href=&quot;/2024/01/22/jinzo-paint-vintage-mobile-drawing-app/&quot;&gt;JINZO Paint&lt;/a&gt;, and I’m always &lt;a href=&quot;/&quot;&gt;blogging&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Don’t forget to &lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;check out my Playdate games in the Catalog Sale!&lt;/a&gt; And my &lt;a href=&quot;/tag/playdate/&quot;&gt;other Playdate blog posts&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;table-wrapper&quot;&gt;
  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Month&lt;/th&gt;
        &lt;th&gt;Project&lt;/th&gt;
        &lt;th&gt;Genre&lt;/th&gt;
        &lt;th&gt;Status&lt;/th&gt;
        &lt;th&gt;Store&lt;/th&gt;
        &lt;th&gt;Blog&lt;/th&gt;
        &lt;th&gt;Made With&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-03&lt;/td&gt;
        &lt;td&gt;Sparrow Solitaire&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/sparrow-solitaire/&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/sparrow-solitaire/&quot;&gt;Catalog&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;/2023/04/13/sparrow-solitaire-for-playdate/&quot;&gt;Read&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://twitter.com/Vogelscript&quot;&gt;vogelscript&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-04&lt;/td&gt;
        &lt;td&gt;Shark Turtle&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;Unreleased&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-05&lt;/td&gt;
        &lt;td&gt;Radical&lt;/td&gt;
        &lt;td&gt;Adventure&lt;/td&gt;
        &lt;td&gt;Abandoned&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-05&lt;/td&gt;
        &lt;td&gt;Carton&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;On hold&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-06&lt;/td&gt;
        &lt;td&gt;Heno Heno&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;On hold&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-06&lt;/td&gt;
        &lt;td&gt;Fore! Track&lt;/td&gt;
        &lt;td&gt;Sports&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/fore-track/&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/fore-track/&quot;&gt;Catalog&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;/2023/06/26/ball-und-panzer-golf-making-a-playdate-game-in-a-week/&quot;&gt;Read&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-07&lt;/td&gt;
        &lt;td&gt;Mandala&lt;/td&gt;
        &lt;td&gt;Toy&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://github.com/gingerbeardman/mandala&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;GitHub&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-08&lt;/td&gt;
        &lt;td&gt;Strategies&lt;/td&gt;
        &lt;td&gt;App&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://gingerbeardman.itch.io/strategies&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;Itch&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-08&lt;/td&gt;
        &lt;td&gt;DateDiff&lt;/td&gt;
        &lt;td&gt;App&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://gingerbeardman.itch.io/datediff&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;Itch&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-08&lt;/td&gt;
        &lt;td&gt;Fortress&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;Abandoned&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-08&lt;/td&gt;
        &lt;td&gt;Mole Hole&lt;/td&gt;
        &lt;td&gt;Adventure&lt;/td&gt;
        &lt;td&gt;Unreleased&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://twitter.com/thoruman&quot;&gt;thoruman&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-09&lt;/td&gt;
        &lt;td&gt;Rink&lt;/td&gt;
        &lt;td&gt;Sports&lt;/td&gt;
        &lt;td&gt;Tutorial&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-09&lt;/td&gt;
        &lt;td&gt;Kye&lt;/td&gt;
        &lt;td&gt;Puzzle&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://mouflon-cloud.itch.io/kye&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;Itch&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://twitter.com/MouflonCloud&quot;&gt;mouflon cloud&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-09&lt;/td&gt;
        &lt;td&gt;YOYOZO&lt;/td&gt;
        &lt;td&gt;Action&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;Catalog&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;/2023/11/21/yoyozo-how-i-made-a-playdate-game-in-39kb/&quot;&gt;Read&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-10&lt;/td&gt;
        &lt;td&gt;Pararena&lt;/td&gt;
        &lt;td&gt;Sports&lt;/td&gt;
        &lt;td&gt;Abandoned&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-10&lt;/td&gt;
        &lt;td&gt;Soccer&lt;/td&gt;
        &lt;td&gt;Sports&lt;/td&gt;
        &lt;td&gt;Prototype&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-10&lt;/td&gt;
        &lt;td&gt;Super ICARUS&lt;/td&gt;
        &lt;td&gt;Action&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/icarus/&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://play.date/games/icarus/&quot;&gt;Catalog&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-11&lt;/td&gt;
        &lt;td&gt;Boing&lt;/td&gt;
        &lt;td&gt;Action&lt;/td&gt;
        &lt;td&gt;Prototype&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-11&lt;/td&gt;
        &lt;td&gt;Cranxious&lt;/td&gt;
        &lt;td&gt;Action&lt;/td&gt;
        &lt;td&gt;Prototype&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2023-12&lt;/td&gt;
        &lt;td&gt;See The Sky&lt;/td&gt;
        &lt;td&gt;Storybook&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://gingerbeardman.itch.io/see-the-sky&quot;&gt;Released&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;Itch&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;/2023/12/16/see-the-sky-thoru-yamamoto-christmas-story-for-playdate/&quot;&gt;Read&lt;/a&gt;&lt;/td&gt;
        &lt;td&gt;&lt;a href=&quot;https://twitter.com/thoruman&quot;&gt;thoruman&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2024-01&lt;/td&gt;
        &lt;td&gt;Rocket Man&lt;/td&gt;
        &lt;td&gt;Simulation&lt;/td&gt;
        &lt;td&gt;On hold&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2024-02&lt;/td&gt;
        &lt;td&gt;Eggdog&lt;/td&gt;
        &lt;td&gt;Action&lt;/td&gt;
        &lt;td&gt;Prototype&lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
        &lt;td&gt; &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

&lt;/div&gt;
</description>
          <author>by Matt Sephton</author>
          <pubDate>Thu, 07 Mar 2024 19:44:00 +0000</pubDate>
          <link>https://blog.gingerbeardman.com/2024/03/07/a-year-in-the-life-of-a-playdate-game-developer/</link>
          <guid isPermaLink="true">https://blog.gingerbeardman.com/2024/03/07/a-year-in-the-life-of-a-playdate-game-developer/</guid>
        </item>
      
    
      
        <item>
          <title>Dynamic music and sound techniques for video games</title>
          <description>&lt;p&gt;The only aspect of game development I’ve not attempted myself is the music. I mostly use royalty free music of Japanese origin (just because I dig their vibe, man) as in the case of &lt;a href=&quot;https://soundcloud.com/mac-vogelsang/sets/sparrow-solitaire&quot;&gt;&lt;em&gt;Sparrow Solitaire&lt;/em&gt;&lt;/a&gt; or &lt;a href=&quot;https://twitter.com/gingerbeardman/status/1732555533863751691&quot;&gt;&lt;em&gt;Fore! Track&lt;/em&gt;&lt;/a&gt; or in rare cases I pay friends (like the amazing Jamie Hamshere) to write music specifically for a game as in the case of &lt;a href=&quot;https://soundcloud.com/gingerbeardman/sets/yoyozo-soundtrack&quot;&gt;&lt;em&gt;YOYOZO&lt;/em&gt;&lt;/a&gt;. Maybe one day that will change, but until then I’m enjoying gaining more understanding and control of the music in my games. Whilst I develop games for &lt;a href=&quot;https://play.date&quot;&gt;Playdate&lt;/a&gt; these techniques are general enough to apply anywhere.&lt;/p&gt;

&lt;p&gt;The main way I make the music into more than a static track is to apply a dynamic, reactive, or adaptive effect in one way or another. In this blog post I’ll go into how I’ve achieved this. Please note this is by no means an exhaustive list, rather it’s just the ones I have personally used.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;dynamic-bpm&quot;&gt;Dynamic BPM&lt;/h2&gt;

&lt;p&gt;I use this method in &lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;&lt;em&gt;YOYOZO&lt;/em&gt;&lt;/a&gt; because it uses “chip tune” music data representing songs composed by my friend Jamie Hamshere using &lt;a href=&quot;https://play.date/pulp/&quot;&gt;&lt;em&gt;Playdate Pulp&lt;/em&gt;&lt;/a&gt;. A playback engine for this data, written by Pulp creator Shaun Inman, works beautifully when integrated into games written using Lua and the &lt;a href=&quot;https://play.date/dev/&quot;&gt;&lt;em&gt;Playdate SDK&lt;/em&gt;&lt;/a&gt;. I added hook to allow me to set the BPM at any point to any value. The end result is that the BPM of the music scales from 130 to 135 as your score increases. As you improve at the game you’ll notice the music speed up ever so slightly along with an increase in tension and anxiety.&lt;/p&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;140&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1685873466&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Of course, it’s possible to do this in a pre-recorded song stored as a digital music file, but it’s much more difficult for that to respond to the what the player does in the game. An example that takes an interesting approach to this is the track &lt;a href=&quot;https://www.youtube.com/watch?v=1_iZh_2li4M&quot;&gt;“Sunny Day” from the game Vib Ribbon&lt;/a&gt;, and indeed the rest of its soundtrack, where tempo changes over the duration of each song.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;infinite-variations&quot;&gt;Infinite Variations&lt;/h2&gt;

&lt;p&gt;Another technique I use in &lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;&lt;em&gt;YOYOZO&lt;/em&gt;&lt;/a&gt;, again made possible because I can modify the music data and playback parameters in real time. With this one I cycle the values for the instrument voices pseudo-randomly so that the track plays once as it was programmed and then morphs slightly for each subsequent playback. The track is quite minimal and repetitive in &lt;a href=&quot;https://sites.barbican.org.uk/reichglassadams/&quot;&gt;Steve Reich, Philip Glass or John Adams&lt;/a&gt; sort of way, so there are automated variations wandering around the original arrangement work really well. Perhaps the &lt;a href=&quot;https://www.youtube.com/watch?v=NkBXgcN3fXo&quot;&gt;ultimate implementation of this approach is &lt;em&gt;Wii Play’s&lt;/em&gt; Tanks game&lt;/a&gt;.&lt;/p&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;140&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; allow=&quot;autoplay&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/1685873439&amp;amp;color=%23ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&amp;amp;show_teaser=true&amp;amp;visual=true&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;For sound effects, I vary the playback sample rate to change the pitch of sound effects. This prevents the same sound effect becoming monotonous. Two examples might be &lt;em&gt;Lara Croft&lt;/em&gt; in the first &lt;em&gt;Tomb Raider&lt;/em&gt; game, &lt;a href=&quot;https://youtu.be/Roi2UelYGsU?si=_17TmHon5JenRxCM&amp;amp;t=1079&quot;&gt;groaning the same way every time she climbs up a platform&lt;/a&gt; compared with &lt;a href=&quot;https://www.youtube.com/watch?v=JGQeQmUuMas&quot;&gt;the rich variety of sounds when &lt;em&gt;Mario&lt;/em&gt; walks on different surfaces&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;blendingfadingbalance&quot;&gt;Blending/Fading/Balance&lt;/h2&gt;

&lt;p&gt;Another idea I had was to fade or blend two tracks as the player makes progress in the game. But how to find two tracks that can be cross-faded in a way that always makes sense? Of course you can have them composed, but what about in music that already exists? If only there was an easy way to find such tracks!&lt;/p&gt;

&lt;p&gt;There is: stereo pairs! You’d be surprised at how different the left and right channels can sound whilst obviously being the same tune. Of course this means that are output audio will be mono but for me on Playdate that’s just fine. I use this method in &lt;a href=&quot;https://play.date/games/fore-track/&quot;&gt;&lt;em&gt;Fore! Track&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The idea is to adjust the balance of the two parts of the audio, at once point you’re playing just the left audio across both outputs, then you adjust the balance to play a mix of both, at the other end of the scale you’d be playing just the right audio. Unfortunately the Playdate SDK currently has no API to easily adjust balance, so I had to program a method myself. First, I convert to the destination format which is for me ADPCM using &lt;a href=&quot;https://github.com/dbry/adpcm-xq&quot;&gt;adpcm-xq&lt;/a&gt;. Once the files are in this format I split the stereo pair into two files, one for the left channel and one for the right channel. Converting to the destination format before splitting ensures that the two are exactly the same length in terms of samples/bytes.&lt;/p&gt;

&lt;p&gt;In the game I fade between the two as the score/chain increases, which has the effect of subtly changing the instrumentation of the tune. It’s one of those things that most people wouldn’t notice, but that once you know about it you can’t miss it. Sadly, I don’t have an easy way to demo this in a video or sound file.&lt;/p&gt;

&lt;p&gt;For sound effects, you might consider panning to increase immersion and guide the players visual focus through use of audio. In &lt;a href=&quot;https://play.date/games/yoyozo/&quot;&gt;&lt;em&gt;YOYOZO&lt;/em&gt;&lt;/a&gt; I pan certain sounds relative to the location of the ball, certain other sounds relative to the location of the player, and there are global sound effects that are not panned at all.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/yoyozo-teaser.gif#playdate&quot; alt=&quot;YOYOZO&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;progressive-loops&quot;&gt;Progressive Loops&lt;/h2&gt;

&lt;p&gt;Digital audio is a different beast. I always try to find a time that fits the game, going so far as to audition many hundreds of tracks and creating playlist of songs far ahead of ever making a game or even having and idea for a game. I try to find tracks that will loop well and not get annoying, which is easier said than done. If I can’t find a track that loops well, there’s another way.&lt;/p&gt;

&lt;p&gt;You can use &lt;a href=&quot;https://github.com/arkrow/PyMusicLooper&quot;&gt;PyMusicLooper&lt;/a&gt; to analyse a digital audio track and spit out information about ranges that loop nicely, along with a percentage indicating how good it considers the loop. In other words you can identify and extract a loop from digital audio files that sound like they could loop. Of course, can’t identify loops in tracks that aren’t repetitive or consistent in their structure.  You might get PyMusicLooper to split the file into into three sections (intro, loop, outro) or just export the loop information as a text file to use in your game. Which I choose depends on how much of the file I want to use.&lt;/p&gt;

&lt;p&gt;For an example, in my game &lt;a href=&quot;https://play.date/games/icarus&quot;&gt;Super ICARUS&lt;/a&gt; I’m using a file that gives the vibe I wanted in the game and sounded like it contained some loops even though it was not provided as a looping song. PyMusicLooper reported that it contains tens of possible loops of varying quality.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;loop&lt;/th&gt;
      &lt;th&gt;start&lt;/th&gt;
      &lt;th&gt;end&lt;/th&gt;
      &lt;th&gt;duration&lt;/th&gt;
      &lt;th&gt;match&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;3.437&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;30.755&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;27.318&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;94.87%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;0.023&lt;/td&gt;
      &lt;td&gt;27.341&lt;/td&gt;
      &lt;td&gt;27.318&lt;/td&gt;
      &lt;td&gt;94.79%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;7.279&lt;/td&gt;
      &lt;td&gt;34.598&lt;/td&gt;
      &lt;td&gt;27.319&lt;/td&gt;
      &lt;td&gt;94.63%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;6.850&lt;/td&gt;
      &lt;td&gt;34.168&lt;/td&gt;
      &lt;td&gt;27.318&lt;/td&gt;
      &lt;td&gt;93.95%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;8.127&lt;/td&gt;
      &lt;td&gt;35.445&lt;/td&gt;
      &lt;td&gt;27.318&lt;/td&gt;
      &lt;td&gt;93.92%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;22.221&lt;/td&gt;
      &lt;td&gt;52.953&lt;/td&gt;
      &lt;td&gt;30.732&lt;/td&gt;
      &lt;td&gt;93.80%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;25.635&lt;/td&gt;
      &lt;td&gt;56.366&lt;/td&gt;
      &lt;td&gt;30.731&lt;/td&gt;
      &lt;td&gt;93.23%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;11.970&lt;/td&gt;
      &lt;td&gt;39.288&lt;/td&gt;
      &lt;td&gt;27.318&lt;/td&gt;
      &lt;td&gt;93.17%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;6.850&lt;/td&gt;
      &lt;td&gt;35.875&lt;/td&gt;
      &lt;td&gt;29.025&lt;/td&gt;
      &lt;td&gt;92.13%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;6.850&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;54.660&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;47.810&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;91.98%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;20.515&lt;/td&gt;
      &lt;td&gt;52.953&lt;/td&gt;
      &lt;td&gt;32.438&lt;/td&gt;
      &lt;td&gt;91.54%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;11&lt;/td&gt;
      &lt;td&gt;10.263&lt;/td&gt;
      &lt;td&gt;37.581&lt;/td&gt;
      &lt;td&gt;27.318&lt;/td&gt;
      &lt;td&gt;91.26%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;22.221&lt;/td&gt;
      &lt;td&gt;54.660&lt;/td&gt;
      &lt;td&gt;32.439&lt;/td&gt;
      &lt;td&gt;91.11%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;13&lt;/td&gt;
      &lt;td&gt;23.928&lt;/td&gt;
      &lt;td&gt;68.325&lt;/td&gt;
      &lt;td&gt;44.397&lt;/td&gt;
      &lt;td&gt;90.92%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;14&lt;/td&gt;
      &lt;td&gt;39.300&lt;/td&gt;
      &lt;td&gt;70.031&lt;/td&gt;
      &lt;td&gt;30.731&lt;/td&gt;
      &lt;td&gt;90.82%&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;12.399&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;70.449&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;58.050&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;90.78%&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;My goal was to find three loops of increasing length and with a high percentage loop quality. After some experimentation and listening, I decided on loops 0, 9, and 15 (table only shows the top 15 loops from this track, even though their percentage loop match are not 100% they still sound like good loops, so selecting these loops was a case of finding three of suitable length and content. PyMusicLooper will let you audition the loops directly, so there’s no need to use an audio editor.&lt;/p&gt;

&lt;p&gt;Using the Playdate SDK I can do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setRange()&lt;/code&gt; on the audio track to change the playback range and the music will loop between those new points when the playhead reaches the end of the range. For this reason, this method does not provide immediate results so is better used to signify a large change in progress as the delay until the change is noticed will be an unknown amount of time. But when the change does kick in it’s a really nice surprise!&lt;/p&gt;

&lt;p&gt;The final result sees the game start by playing loop 1 (synth and drums) and then as the player gets makes some good progress I switch to loop 2 (synth, drums, guitar licks), and finally as they pass a certain threshold I switch to loop 3 (synth, drums, guitar licks into guitar solo). This provides music that sounds very dynamic with little effort. You could even drop back to the shorter loops if the player lost a life, missed a target, and so on. Again, there’s no real way of me demoing this as it’s something that will become apparent through play, and the final result is just one long dynamic song!&lt;/p&gt;

&lt;p&gt;For sound effects I use the same approach as above. As an example, in &lt;a href=&quot;https://play.date/games/fore-track/&quot;&gt;&lt;em&gt;Fore! Track&lt;/em&gt;&lt;/a&gt; there is a clapping sound effect after the player gets the ball in a hole. This is a long sound effect but I play three increasingly long sections of it as the player’s chain increases (number of successive holes-in-one). It starts off as a short clap, increases to a longer more enthusiastic clap, and finally it begins with a whoop and continues to enthusiastic clap. I have a separate sound effect for the end game cheer that plays over the top of the full clap, resulting in a raucous end of game celebration.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;quantised-sounds&quot;&gt;Quantised Sounds&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;https://play.date/games/icarus&quot;&gt;Super ICARUS&lt;/a&gt; created certain game event sounds from small sections of the music track. I then adjust playback rate/speed/pitch. The result is that the sounds appear to be quantised or matched to the music. I’m not sure how to describe this phenomenon accurately in musical/technical terms.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I’d love to hear about other methods of achieving dynamic music and sound in video games. Feel free to reach out to me on social media!&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;further-reading&quot;&gt;Further reading&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2023/11/21/yoyozo-how-i-made-a-playdate-game-in-39kb/&quot;&gt;&lt;em&gt;YOYOZO&lt;/em&gt; (or, how I made a Playdate game in 39KiB)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2023/11/26/easter-egg-emoji-converting-pixels-into-particles/&quot;&gt;Easter egg emoji: converting pixels into particles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2023/12/09/dynamic-music-and-sound-techniques-for-video-games/&quot;&gt;Dynamic music and sound techniques for video games&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;elsewhere&quot;&gt;Elsewhere&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;2023-11-22—&lt;a href=&quot;https://news.ycombinator.com/item?id=38584336&quot;&gt;Hacker News&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2023-11-22—&lt;a href=&quot;https://tildes.net/~games/1crg/dynamic_music_and_sound_techniques_for_video_games&quot;&gt;Tildes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <author>by Matt Sephton</author>
          <pubDate>Sat, 09 Dec 2023 01:22:00 +0000</pubDate>
          <link>https://blog.gingerbeardman.com/2023/12/09/dynamic-music-and-sound-techniques-for-video-games/</link>
          <guid isPermaLink="true">https://blog.gingerbeardman.com/2023/12/09/dynamic-music-and-sound-techniques-for-video-games/</guid>
        </item>
      
    
      
        <item>
          <title>Ball und Panzer Golf: making a Playdate game in a week</title>
          <description>&lt;p&gt;I’ve been following the X68000 Z mini computer since it’s announcement in the hope that it will bring new activity to the X68000 scene and it seems to be having that effect. In one video from the recent 「68の日」(“68 Day”, named after the date written in Japanese order, 6-8, that’s 8th June the most special day of the year for X68000 fans) &lt;a href=&quot;https://twitter.com/gingerbeardman/status/1669909753592512512?s=61&amp;amp;t=vJGphXuN310nHUu1fN6c7Q&quot;&gt;I spotted&lt;/a&gt; a interesting looking single screen golf game:&lt;/p&gt;

&lt;lite-youtube style=&quot;aspect-ratio: 16/9;&quot; videoid=&quot;Nwte3wm6lzo&quot; params=&quot;start=0&amp;amp;modestbranding=2&quot;&gt;
&lt;/lite-youtube&gt;

&lt;h2 id=&quot;hello-kata68k&quot;&gt;Hello kata68k&lt;/h2&gt;

&lt;p&gt;It was Ball und Panzer Golf an indie/doujin game by &lt;a href=&quot;https://twitter.com/kata68k&quot;&gt;@kata68k&lt;/a&gt; for the Sharp X68000 series of Japanese personal computers and the recent &lt;a href=&quot;https://www.zuiki.co.jp/products/x68000z/&quot;&gt;&lt;em&gt;Zuiki X68000 Z&lt;/em&gt;&lt;/a&gt; mini system, a new emulator based reimagining of the original classic computer. The name is a pun on the anime series &lt;a href=&quot;https://en.wikipedia.org/wiki/Girls_und_Panzer&quot;&gt;&lt;em&gt;Girls und Panzer&lt;/em&gt;&lt;/a&gt; and its shortened version is &lt;em&gt;BuPG&lt;/em&gt; which I assume is a pun on &lt;em&gt;PUBG&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;kata68k’s game, as the name implies, is golf but with a tank. It was &lt;a href=&quot;https://twitter.com/kata68k/status/1634209609069076480&quot;&gt;created in May 2023 and fine tuned for a few weeks&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/kata68k/status/1666099628947968006&quot;&gt;released in time for “68 Day”&lt;/a&gt;. It’s a single player game where you use the tank to shoot holes-in-one on a golf course and try to destroy all flags. All this to say it plays like golf, kinda, but with a focus on high scores.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Aside: my favourite source of X68000 content is the &lt;a href=&quot;https://www.youtube.com/user/pipipicpsf&quot;&gt;&lt;em&gt;PipitanTV&lt;/em&gt; YouTube channel&lt;/a&gt;, run by &lt;a href=&quot;https://twitter.com/pipixvi&quot;&gt;@pipixvi&lt;/a&gt;, which has a &lt;a href=&quot;https://www.youtube.com/watch?v=FMrsHfuuTR8&amp;amp;t=22s&quot;&gt;longer, screen capture video&lt;/a&gt; of Ball und Panzer Golf.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I played Ball und Panzer Golf v0.94 using an X68000 emulator and was instantly hooked, by the strange mashup concept and also by the scoring mechanisms that were involved. Kata’s game design values and methods align with my own to a surprising degree. kata68k grew up with the X68000 much like I grew up with another Motorola 68000-based computer: the Atari ST. We’re roughly the same age and have similar interests in many ways.&lt;/p&gt;

&lt;p&gt;Anyway, I had great fun figuring out the different types of shots and opportunities to increase my scoring ability during my few plays of the game. Once I’d figured them out, it became a task of improving my skill controlling the tank and the shot power. The shot mechanism itself is worthy of a mention: there is no real charging of the shot and the ball starts to move immediately. What you do control is the moment the ball starts to come back down to Earth. It’s a very strange way of controlling the ball, but oddly satisfying. It’s reminiscent of the two tap system that sets power in most golf games, but at the same time feels completely alien.&lt;/p&gt;

&lt;h2 id=&quot;enter-playdate&quot;&gt;Enter Playdate&lt;/h2&gt;

&lt;p&gt;I currently spend my time creating games for &lt;a href=&quot;https://play.date&quot;&gt;Playdate&lt;/a&gt;, a handheld gaming system with a black and white screen and a unique crank control that can be used as a method of input. Whilst on a walk in the park I couldn’t stop thinking of kata68k’s game and how it might work on Playdate. When I got back to my computer I wrote a little bit of Lua code to draw an elliptical golf green on screen, then added a hole, a flag pole, and a flag with a number on it. Then I added a loop to generate random positions and drew 18 holes, adjusting the size so they all fitted a bit better. It might just work.&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-01.png#playdate&quot; alt=&quot;PNG&quot; title=&quot;The first 18 holes, eat your heart out &amp;lt;em&amp;gt;Pebble Beach no Hatou&amp;lt;/em&amp;gt;!&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After a quick dinner, it was time to draw the tank. I really didn’t want to slow down my pace of progress so I decided to keep drawing the graphical elements in code using filled shapes rather then have to draw a tank in pixels. Another option would have been to use one of the cars from my game &lt;a href=&quot;/2021/08/23/daily-driver-teaser-artwork/&quot;&gt;Daily Driver&lt;/a&gt;, but the path of least resistance was to draw a filled ellipse along with a line to show the turret position.&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-02.png#playdate&quot; alt=&quot;PNG&quot; title=&quot;Rudimentary tank and turret drawn using an filled ellipse and a thick line&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;day-1&quot;&gt;Day 1&lt;/h2&gt;

&lt;p&gt;That first day everything fell into place perfectly, with little friction and no refactoring. I started from a blank file and wrote just under 400 lines of code. The two most complicated elements were the randomised background and limiting the tank to its circular area, but I’d done similar things before so there was no problem solving involved, just pure implementation. In fact, a lot of this quick prototype made use of tricks and techniques I’d figured out over the past few years of Playdate development, in particular during the development of my game &lt;a href=&quot;/tag/dailydriver/&quot;&gt;Daily Driver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the end of the first day you could drive the tank around the screen, fire the ball at an angle selected using the crank or d-pad, and when you run out of balls it would trigger game over. What it didn’t have is any logic that would collide the ball with the holes, point scoring, or any sort of win state. For some reason at this point I thought it would be cool to have a black tank with three wheels.&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-03.gif#playdate&quot; alt=&quot;GIF&quot; title=&quot;The state of the game the end of the first day&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;day-1-timeline&quot;&gt;Day 1: Timeline&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Time&lt;/th&gt;
      &lt;th&gt;Event&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;15:40&lt;/td&gt;
      &lt;td&gt;draw a single “hole”: flag, hole, green&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;16:00&lt;/td&gt;
      &lt;td&gt;loop to draw 18 holes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;17:00&lt;/td&gt;
      &lt;td&gt;(dinner)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;18:00&lt;/td&gt;
      &lt;td&gt;draw tank&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;18:20&lt;/td&gt;
      &lt;td&gt;(ask permission from kata68k)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;19:00&lt;/td&gt;
      &lt;td&gt;background (interesting use of Perlin and random)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20:00&lt;/td&gt;
      &lt;td&gt;add controls to tank&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20:10&lt;/td&gt;
      &lt;td&gt;(send update to kata68k)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;21:00&lt;/td&gt;
      &lt;td&gt;limit tank to circular area (tricky but fun)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;22:00&lt;/td&gt;
      &lt;td&gt;ball moving&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;22:10&lt;/td&gt;
      &lt;td&gt;(kata68k confirms he’s OK with my version)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;22:30&lt;/td&gt;
      &lt;td&gt;add game states&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;23:00&lt;/td&gt;
      &lt;td&gt;add ball height capability&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;23:45&lt;/td&gt;
      &lt;td&gt;(send update to kata68k)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;00:26&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://twitter.com/gingerbeardman/status/1670573820581650434&quot;&gt;tweet about it&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;week-1&quot;&gt;Week 1&lt;/h2&gt;

&lt;p&gt;The following day I added a first draft of collisions and scoring. There was slower progress, but it was still very steady with no problems encountered. I was keenly aware that the collision and scoring were very naïve and that I would have to refine and improve them going forward. But, regardless, at the end of the second day it was possible to play a complete round of tank golf!&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-04.gif#playdate&quot; alt=&quot;GIF&quot; title=&quot;How the game was shaping up at the end of the second day&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The next two days consisted of fine tuning, polishing, play testing, bug fixing, adding sound effects, and so on. I even managed to record a GIF where I got all 18 flags …my first speed run!? I also received some great early encouragement and feedback from Playdate Squad community members: Donald &lt;a href=&quot;https://twitter.com/Guv_Bubbs&quot;&gt;@Guv_Bubbs&lt;/a&gt;, Steve &lt;a href=&quot;https://twitter.com/ScenicSoftware&quot;&gt;@ScenicSoftware&lt;/a&gt;, Atsu &lt;a href=&quot;https://twitter.com/SquidGodDev&quot;&gt;@SquidGodDev&lt;/a&gt;, Neven &lt;a href=&quot;https://twitter.com/mrgan&quot;&gt;@neven&lt;/a&gt; and of course &lt;a href=&quot;https://twitter.com/kata68k&quot;&gt;@kata68k&lt;/a&gt; himself! The game was shaping up nicely and coming together very quickly.&lt;/p&gt;

&lt;p&gt;Opportune timing meant that I could get the game in the hands of some testers on a live stream, over at IGDA Twin Cities (MN, USA) as part of their monthly Playtest. Thanks to &lt;a href=&quot;https://twitter.com/Mark_LaCroix&quot;&gt;Mark LaCroix&lt;/a&gt; for sorting that out! It was great to watch them play the game for the first time as they discovered the details of gameplay, mechanics, controls, and scoring! I even spotted a bug.&lt;/p&gt;

&lt;lite-youtube style=&quot;aspect-ratio: 16/9;&quot; videoid=&quot;qZq3-N1MczA&quot; params=&quot;start=3837&amp;amp;modestbranding=2&quot;&gt;
&lt;/lite-youtube&gt;

&lt;p&gt;For the rest of the week I polished and played, addressing areas that I thought could be improved. I added accessibility improvements, more opportunities to score, better hole randomisation, even wind effects, and so much more besides.&lt;/p&gt;

&lt;p&gt;For the last couple of days of the week I kept release notes, as I felt the pace of progress slowing down towards the end of my self-imposed deadline of one week. I would categorise most changes in those final days as either quality of life improvements or minor bug fixes.&lt;/p&gt;

&lt;p&gt;I had not optimised any of the code and was targeting the default 30 frames per second. On the final evening I optimised all text drawing in my main update path, as I could see that was responsible for a huge portion of where my game was spending its time, with the CPU pegged at 100% and the frame rate not able to hit the target 30fps. So the flags with numbers on were pre-rendered as images during initialisation, and the HUD is drawn only when its contents change, and the image is cached for use at other times. These two small and quick optimisations reduced the CPU usage by 20% and put me at a solid 30fps.&lt;/p&gt;

&lt;p&gt;There are many more optimisations to be made but this is not the time to do them. There’s too much still to do and I don’t want to lose focus. But for example: I’m not currently using the Playdate SDK Sprite system and am instead doing things the traditional way of drawing everything every update, so I’m positive I can get some good gains by drawing to a few different sprite layers. There are also some functions I call regularly, such as one that counts remaining holes, that can be optimised or avoided by improving my game logic. I’m confident I can get the CPU time down a good bit more. There’s no real need to do so, but I figure anything that will help reduce power usage or is good for the player is a honourable responsibility for a developer with a conscience to take on. If that goes well I may even increase the frame rate for smoother ball movement.&lt;/p&gt;

&lt;h2 id=&quot;shaping-up&quot;&gt;Shaping up&lt;/h2&gt;

&lt;p&gt;All the graphics are still composed with filled ellipses, rectangles and lines, varying their dithering patterns to provide different textures. I really leaned into this and over the course of the week fine tuned the tank from a three-wheeled blob to a high contrast, detailed, carefully animated sprite that you might think has been rendered externally. Maybe in a forthcoming post I can put together an exploded diagram of how it’s drawn?&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-05.gif#playdate&quot; alt=&quot;GIF&quot; title=&quot;Ball und Panzer Golf for Playdate, at the end of the first week&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;

&lt;p&gt;The only things I didn’t manage to fit in in my week sprint were a couple of animations I think will help make the game feel even higher quality and that will increase players ability to read/understand what is happening on screen. I need to make some more changes to the wind feature and the way the flag flaps in the wind. Currently the flag direction is correct but I’d like the length and frequency to be relative to the strength of the wind.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Pretty much all of the maths in this game is high school algebra and trigonometry, wrapped up in some smoke and mirrors to make it feel magical.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also on the task list are a couple more sound effects, with the goal being one sound effect for each important event or action in the game. I feel that sounds cues are as important as visual cues and players could pick up on one or the other so there should ideally be parity.&lt;/p&gt;

&lt;p&gt;I can’t keep up the insanely fast pace of development from this first week, not only because of the physical and mental toll it would take but also because the quick wins of the prototype phase are now gone. To add the animations I previously mentioned, the first serious refactoring of part of the code will be needed. So there is no choice but for progress to be slower from this point at least for a while.&lt;/p&gt;

&lt;p&gt;The big remaining task that will take a lot longer than a week is game structure and progression. I have ideas of how I can package the structure of the game now into a short experience with increasing difficulty level and unlimited replay-ability.&lt;/p&gt;

&lt;p&gt;But the bigger question is do I want it to be bigger than that? There are no shortage of ideas how how to mashup to concept of tanks and golf, only a shortage of time and budget to make it happen. I could even add a mini-golf type of experience where you’re playing a round of single screen holes with additional hazards pulled from both the golf and tank world.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;launched&quot;&gt;Launched!&lt;/h2&gt;

&lt;p&gt;My version of Ball und Panzer Golf was renamed Fore! Track and is available for Playdate via Catalog &lt;a href=&quot;https://play.date/games/fore-track/&quot;&gt;play.date/games/fore-track/&lt;/a&gt; or on &lt;a href=&quot;https://gingerbeardman.itch.io/fore-track&quot;&gt;itch where there’s a bargain offline version&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;tofigure&quot;&gt;&lt;img src=&quot;https://cdn.gingerbeardman.com/images/posts/ball-und-panzer-golf-fore-track.gif#playdate&quot; alt=&quot;GIF&quot; title=&quot;Demonstration of the launch version of &amp;lt;em&amp;gt;Fore! Track&amp;lt;/em&amp;gt;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;further-reading&quot;&gt;Further reading&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/2023/07/09/the-first-colour-playdate-game/&quot;&gt;The first colour Playdate game?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
          <author>by Matt Sephton</author>
          <pubDate>Mon, 26 Jun 2023 22:11:00 +0000</pubDate>
          <link>https://blog.gingerbeardman.com/2023/06/26/ball-und-panzer-golf-making-a-playdate-game-in-a-week/</link>
          <guid isPermaLink="true">https://blog.gingerbeardman.com/2023/06/26/ball-und-panzer-golf-making-a-playdate-game-in-a-week/</guid>
        </item>
      
    

  </channel>
</rss>
