{"id":520,"date":"2025-07-18T21:43:21","date_gmt":"2025-07-18T21:43:21","guid":{"rendered":"https:\/\/mityjohn.com\/?p=520"},"modified":"2025-07-19T12:46:16","modified_gmt":"2025-07-19T12:46:16","slug":"from-hitster-to-hipster-building-a-music-game-with-agentic-ai-in-just-2-evenings","status":"publish","type":"post","link":"https:\/\/mityjohn.com\/?p=520","title":{"rendered":"From Hitster to Hipster: Building a Music Game with Agentic AI in Just 2 Evenings"},"content":{"rendered":"\n<p>At some point, we all hit that wall with a board game we love. For me, that was <strong>Hitster<\/strong>\u2014a brilliant concept of guessing and ordering songs by release year. But after a few rounds, we ran out of cards\u2026 and noticed the playlist leaned heavily towards <strong>Dutch (from the Netherlands)<\/strong> songs.<\/p>\n\n\n\n<p>As a Belgian (and Flemish), I just didn\u2019t know many of them\u2014and neither did my wife and kids. So I did what any slightly frustrated developer with a toolbox full of AI would do:<\/p>\n\n\n\n<p><strong>I built my own.<\/strong><\/p>\n\n\n\n<p>Welcome to <strong>Hipster<\/strong> \u2013 a fast-paced, web-based version of Hitster, lovingly crafted with <strong>TypeScript<\/strong>, <strong>Vue.js<\/strong>, and some serious AI help.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"604\" src=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-5.png\" alt=\"\" class=\"wp-image-531\" srcset=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-5.png 693w, https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-5-300x261.png 300w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/figure>\n\n\n\n<p><strong>Play it now<\/strong>: <a class=\"\" href=\"http:\/\/hipster.mityjohn.com\/\">hipster.mityjohn.com<\/a><br><strong>Fork it here<\/strong>: <a class=\"\" href=\"https:\/\/github.com\/janvanwassenhove\/Hipster\">GitHub: janvanwassenhove\/Hipster<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Stack (and the Magic Behind It)<\/h2>\n\n\n\n<p>I kicked off the prototype using <strong><a class=\"\" href=\"https:\/\/bolt.diy\">bolt.diy<\/a><\/strong> \u2013 my go-to low-code prototyping tool for rapidly building logic flows and triggering actions.<\/p>\n\n\n\n<p>From there, I co-developed the app with <strong>Claude Sonnet 4<\/strong>, which proved to be a powerful agentic AI partner. With clear instructions and task-oriented prompting, Claude generated reliable TypeScript and Vue 3 code with an uncanny sense of structure. Like having a junior dev who works at lightspeed and never goes on coffee break.<\/p>\n\n\n\n<p>To streamline and autocomplete repetitive coding bits, I used <strong>GitHub Copilot<\/strong>. Especially handy in Vue components and managing state across the game.<\/p>\n\n\n\n<p>Total dev time? Just <strong>6 hours<\/strong>, split across <strong>two evenings<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"606\" height=\"1024\" src=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-2-606x1024.png\" alt=\"\" class=\"wp-image-522\" style=\"width:387px;height:auto\" srcset=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-2-606x1024.png 606w, https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-2-178x300.png 178w, https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-2.png 641w\" sizes=\"auto, (max-width: 606px) 100vw, 606px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">How the Game Works<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Each player takes turns guessing when a song was released, and placing it correctly on a growing <strong>timeline<\/strong>.<\/li>\n\n\n\n<li>Songs are played using the <strong>Spotify Web Playback SDK<\/strong> or Web API.<\/li>\n\n\n\n<li>A correct guess earns you <strong>tokens<\/strong> and <strong>bonus points<\/strong>.<\/li>\n\n\n\n<li>The more songs added to the timeline, the harder it gets.<\/li>\n<\/ul>\n\n\n\n<p>All state is stored locally in the browser, which makes it quick and simple to play with friends\u2014no login or database needed (except for Spotify access).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Real MVP Struggle: Mobile Playback<\/h2>\n\n\n\n<p>While the AI side of this project felt like smooth sailing\u2014rapid prototyping, fast iterations, and solid TypeScript generation\u2014the real test wasn\u2019t with Claude or Copilot.<\/p>\n\n\n\n<p><strong>It was getting Spotify playback to work reliably on mobile.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"534\" height=\"569\" src=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-3.png\" alt=\"\" class=\"wp-image-523\" style=\"width:359px;height:auto\" srcset=\"https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-3.png 534w, https:\/\/mityjohn.com\/wp-content\/uploads\/2025\/07\/image-3-282x300.png 282w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" \/><\/figure>\n\n\n\n<p>That\u2019s where years of <strong>developer grit<\/strong> and <strong>architectural experience<\/strong> kicked in.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <strong>Spotify Web Playback SDK<\/strong> only works on <strong>desktop browsers<\/strong>.<\/li>\n\n\n\n<li>On mobile, you&#8217;re forced to fall back to the <strong>Spotify Web API<\/strong>, which can only control external devices\u2014so playback has to happen in the <strong>native Spotify app<\/strong>.<\/li>\n\n\n\n<li>Add to that: autoplay restrictions, token handling, device activation quirks, and iOS&#8217;s delightful habit of blocking anything that looks remotely fun.<\/li>\n<\/ul>\n\n\n\n<p>AI didn\u2019t magically solve that. I had to <strong>design around limitations<\/strong>, handle edge cases, and build in fallback flows that keep the game experience snappy\u2014even if the user is being bounced between browser and app.<\/p>\n\n\n\n<p>In short: <strong>AI accelerated the build<\/strong>, but <strong>human experience made it playable<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Deployed via GitHub Pages<\/h2>\n\n\n\n<p>To keep the project lean and serverless, I deployed Hipster using <strong>GitHub Pages<\/strong>. Everything runs client-side:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Vue.js frontend<\/li>\n\n\n\n<li>Spotify authentication and playback<\/li>\n\n\n\n<li>Local storage for game state<\/li>\n<\/ul>\n\n\n\n<p>No backend, no hosting fees, and just a few seconds to load up the game.<\/p>\n\n\n\n<p>You can play it now at:<br><a class=\"\" href=\"http:\/\/hipster.mityjohn.com\">http:\/\/hipster.mityjohn.com<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why I Built This<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Because <strong>Hitster<\/strong> ran out of cards too quickly.<\/li>\n\n\n\n<li>Because I wanted a playlist that included more <strong>Flemish<\/strong> songs I actually knew.<\/li>\n\n\n\n<li>Because building playful, personal tools with AI is too fun not to do.<\/li>\n<\/ul>\n\n\n\n<p>What started as a mid-week hack quickly became a working game\u2014and a great demo of how accessible solo software projects can become with the help of AI copilots and agents.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bonus Round: Remix It<\/h2>\n\n\n\n<p>Want to fork it? Add your own playlist logic? Translate it to your language (other thand Dutch, German, English or French) or apply your own style?<\/p>\n\n\n\n<p>It&#8217;s open source and ready to remix:<br><a class=\"\" href=\"https:\/\/github.com\/janvanwassenhove\/Hipster\">https:\/\/github.com\/janvanwassenhove\/Hipster<\/a><\/p>\n\n\n\n<p>Let\u2019s make the next wave of casual games\u2014AI-built, fast, fun, and tailored to the players!<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>At some point, we all hit that wall with a board game we love. For me, that was Hitster\u2014a brilliant concept of guessing and ordering songs by release year. But after a few rounds, we ran out of cards\u2026 and noticed the playlist leaned heavily towards Dutch (from the Netherlands) songs. As a Belgian (and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":527,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-520","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development"],"_links":{"self":[{"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/posts\/520","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mityjohn.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=520"}],"version-history":[{"count":6,"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/posts\/520\/revisions"}],"predecessor-version":[{"id":533,"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/posts\/520\/revisions\/533"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mityjohn.com\/index.php?rest_route=\/wp\/v2\/media\/527"}],"wp:attachment":[{"href":"https:\/\/mityjohn.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mityjohn.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mityjohn.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}