<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Godot on foosel.net</title><link>https://foosel.net/tags/godot/</link><description>Recent content in Godot on foosel.net</description><generator>Hugo</generator><language>en-us</language><copyright>Gina Häußge (foosel)</copyright><lastBuildDate>Tue, 30 May 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://foosel.net/tags/godot/index.xml" rel="self" type="application/rss+xml"/><item><title>Developing "Pew Pew Pew: Danger Zone!"</title><link>https://foosel.net/blog/2023-05-30-developing-pew-pew-pew-danger-zone/</link><pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2023-05-30-developing-pew-pew-pew-danger-zone/</guid><description>A bit of a devlog for my Go Godot Jam 4 entry</description><content:encoded><![CDATA[<p>As hinted at to be my plan in <a href="/blog/2023-04-16-the-path-to-super-bunny-hoppers/">my post about my first proper gamedev experience back in April</a>, I recently took part in my first
ever gamejam, <a href="https://itch.io/jam/go-godot-jam-4">Go Godot Jam 4</a>, and during that built a game called <a href="https://foosel.itch.io/pew-pew-pew-danger-zone">&ldquo;Pew Pew Pew: Danger Zone!&rdquo;</a>. The jam required all submissions to be built in <a href="https://godotengine.org">Godot Engine</a>, which was one of the reasons I chose it - I just recently got my feet wet in game development with Godot 4 and wanted to get some more practice in. Since my partner was otherwise committed, I entered as a solo dev.</p>
<p>In this post I want to share a bit of a devlog and some insights into that experience, to add more background to <a href="https://chaos.social/@foosel/110321340611941751">the Mastodon thread I maintained throughout</a>.</p>
<p>Apologies in advance, this is going to be a long one, but there are also a ton of pictures and videos to break up the text a bit 😉</p>
<h2 id="development">Development</h2>
<p>The submission phase (so the time I had for developing and submitting a game fitting the theme) was 9 days long, from Friday, May 5th at 22:00 UTC to Sunday, May 14th at 22:00 UTC. Since the start wasn&rsquo;t until midnight in my timezone and after yet another intense work week I was quite exhausted on that Friday evening, I didn&rsquo;t stay up for the theme announcement. So it wasn&rsquo;t before the morning of Satuday May 6th for me to learn about the theme <strong>LESS IS MORE</strong>, right after waking up.</p>
<h3 id="saturday-may-6th-lets-go">Saturday, May 6th: Let&rsquo;s go!</h3>
<p>During my morning routine I got an idea on what game to create<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>: A little shoot-em-up (shmup) with minimalistic graphics, slightly bullet hell-ish, where the only way to upgrade your weapon and shoot more bullets was to lose health. The challenge would be balancing health vs damage output, possibly even dodging health pickups to stay at a higher bullet output with the risk of dying.</p>
<p>After breakfast I sat down to sketch out this idea a bit further.</p>
<p><img alt="My handwritten and handrawn notes of the game idea" loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-notes.webp"></p>
<p>The originally plan was to have the player be a triangle pointing upwards, and several enemy types also based on geometric shapes. The player would have three hit points and thus three different bullet emitter configurations. I jotted down some ideas for collectable power-ups (a shield, health, little shooting satellites, homing missiles), did some initial UI sketches and also laid out a rough plan for the interactive tutorial I wanted to include, by already leaving myself a plan B in case I wouldn&rsquo;t have enough time to implement it. Not written down in my notes but already quite clear in my head was the plan to have the game have 2-3 levels and a final boss to defeat, which felt like a good scope for the time I had available.</p>
<p>The plan was to spend most of the time until maybe Wednesday implementing controls, enemies, bullets and the basic game loop, and then spending the rest of the time on the tutorial, levels and boss, plus of course testing and publishing on <code>itch.io</code>.</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110321340611941751">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p><a href="https://chaos.social/tags/GoGodotJam4" class="mention hashtag" rel="tag">#<span>GoGodotJam4</span></a> started at midnight. The theme is &quot;Less is more&quot; and I intend to participate! Got an idea that should work I hope, so let the coding commence!</p>
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110321340611941751" class="toot-date" rel="noopener">May 6, 2023, 10:47</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<p>Then I sat down and got to work.</p>
<p>My first task was getting a player scene created and basic 2d movement controls implemented. After that I quickly created a player asset, two enemy assets and some bullets in Inkscape, basing my color choices on the <a href="https://lospec.com/palette-list/endesga-64">ENDESGA 64 color palette</a>, and started looking into automatic bullet emitters and bullet patterns for the enemies, and straight shooting for the player. I also implemented the logic for the player to lose health when colliding with the enemies&rsquo; bullets and consequently shooting more bullets, and for the enemies to lose health and dying when colliding with the player&rsquo;s bullets.</p>
<p>All of that took me the better part of Saturday, but by the time evening got around I had a very basic prototype with bullet emitters and patterns on the (still static) enemies and some basic shooting logic on the player. There was no sound yet, no game juice, nothing like that, but it was a start!</p>
<video controls preload="auto" width="100%"  autoplay loop playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day1.webm" type="video/webm">
  <span></span>
</video>
<h3 id="sunday-may-7th-lets-add-some-game-juice">Sunday, May 7th: Let&rsquo;s add some game juice!</h3>
<p>Sunday began with a trip to a doc to get my sixth COVID shot<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. After that I sat down again in front of the laptop to implement as much as I could before the by now customary post-vaccination-headache would start haunting me.</p>
<p>It turned out to be a quite busy day, as I implemented:</p>
<ul>
<li>screen scrolling and movement limits for the player to always stay on screen</li>
<li>player death and respawning at the bottom of the screen, with a short period of invincibility right after respawning indicated by some fading in and out</li>
<li>screenshake and an explosion particle effect when destroying an enemy or the player</li>
<li>some basic sound effects for shooting and the explosions, whipped up in <a href="https://github.com/timothyqiu/gdfxr">gdfxr</a></li>
<li>a simple shadow effect for the player and enemies to simulate height (really just the same sprite with a modulate color applied and offset by a few pixels)</li>
</ul>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day2.webm" type="video/webm">
  <span></span>
</video>
<p>I also did some research on what music to put in and came across some amazing tracks by <a href="https://davidkbd.itch.io/">David KBD</a>. I was not yet fully set on which tracks to use precisely, but I was sure I had found a match (and was right!).</p>
<p>I was quite happy with that kind of progress and went to sleep with a good feeling, despite dreading the next day a bit due to the expected side effects of the vaccination.</p>
<h3 id="monday-may-8th-its-got-a-name">Monday, May 8th: It&rsquo;s got a name!</h3>
<p>But when I woke up on Monday morning, I happily realized that this time I had gotten away with just a bit of a headache and some tiredness, but nothing more. Alas, that still didn&rsquo;t allow me to continue to work on the game - it was a regular work day after all! And so I had to wait until the evening to continue. I was able to implement some pluggable enemy behaviour (for now only following the player at an offset, but with an underlying code structure that would allow to quickly implement other behaviours as well) and also a first version of the HUD with health bar, damage output bar, life counter and score display. Also, I whipped up a background graphic in Inkscape and put that in as well. But most importantly I came up with a name for my creation: <strong>Pew Pew Pew: Danger Zone!</strong></p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day3.webm" type="video/webm">
  <span></span>
</video>
<h3 id="tuesday-may-9th-pickups">Tuesday, May 9th: Pickups!</h3>
<p>Just as Monday, Tuesday would also be a slower day with regards to progress on the game - working on OctoPrint all day didn&rsquo;t leave much time and energy in the evenings to make huge steps forward<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>, but I got some more stuff done nevertheless and was able to add various pickups to the game:</p>
<ul>
<li>a health pickup that would recover one hit point for the player (which of course would reduce the damage output),</li>
<li>a shield pickup that would protect the player from bullet damage for a few seconds,</li>
<li>point pickups and</li>
<li>a pickup that would add a little drone circling around the player which for now did nothing but in the future I wanted to have shoot homing missiles at the closest enemy</li>
</ul>
<p>Almost all of that would of course see further fine tuning during the next few days, but it was a good start on the pickups.</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day4.webm" type="video/webm">
  <span></span>
</video>
<h3 id="wednesday-may-10th-refactoring--doubting-myself">Wednesday, May 10th: Refactoring &amp; doubting myself!</h3>
<p>Wednesday was the worse day of the jam for me. Work was tough, I was really out of energy in the evening, and the time that I did have after work was spent on refactoring the bullet emitters on the enemies so that I could also use them for the player and setting up some more bullet patterns, during which I also managed to introduce a hilarious bug that doubled all of the emitted bullets, making the game incredibly hard.</p>
<p><img alt="A screenshot from PPP:DZ. Most of the screen is filled with bullets thanks to the duplication bug." loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day5.png"></p>
<p>That was also the day I spent a lot of time on trying to get the drone to work and failing miserably - the homing missiles just didn&rsquo;t feel right, a circular pattern I tried as an alternative felt even worse, and all in all it simply was not coming together. I knew I still didn&rsquo;t have a single level, the drone idea was failing and I was thinking I&rsquo;d have to pull it, and things just still didn&rsquo;t feel very fun. All in all, I was starting to seriously doubt whether I&rsquo;d be able to submit something to the jam that I could be proud of. I went to bed quite frustrated and in doubt with myself.</p>
<h3 id="thursday-may-11th-menus-bombs-game-over">Thursday, May 11th: Menus, bombs, game over!</h3>
<p>Thursday was a way better day however! I woke up very early, and when I realized I could no longer sleep got up and went through my morning routine. I was still thinking a lot about the drone and how to fix it, when suddenly a shower thought struck. I&rsquo;d implement another pickup, a little bomb that you&rsquo;d be able to trigger with a button press and which would then damage all enemies in its radius for a large amount of points and eradicate all bullets and pickups.</p>
<p>I finished my routine, sat down in front of the computer and started working on that - even before work! It was around 7am and I figured I should be able to get that implemented in the 2-2.5h before I had to start working on OctoPrint, and it turns out I indeed managed to pull that off! I created a small effect to indicate the damage radius of the bomb that would get attached to the player when the bomb was picked up, and a small animation that would make this light up and vanish when the bomb was set off via the <code>Shift</code> key, together with a new sound effect. And doing that was fun! I was starting to feel optimistic again and started on my work day.</p>
<p>I finished that a bit earlier than usual because I had accumulated some overtime the past few weeks and got back into working on PPP:DZ. I fixed the homing missiles on the drone - they were not perfect, but they were finally homing! I also created a title graphic, the game&rsquo;s menu, a pause menu, a game over and a winning screen, some pickup indicators for the HUD, made level switching work, and changed some things about the pickups - the drone would now time out, the shield would track damage and be able to protect from 10 damage points. I think this was also the day I had the idea to give the player a bit of gravity for pulling in pickups, and that also made things finally feel way nicer!</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/ggj4-day6.webm" type="video/webm">
  <span></span>
</video>
<p>It was an incredibly productive day, and I knew I&rsquo;d be able to fully concentrate on the game for all of Friday, Saturday and Sunday. I set myself the goal to finish a first level by the end of the next day, add two more levels and a boss fight on Saturday, and do nothing but testing and bug fixing for all of Sunday.</p>
<p>I went to bed feeling like I might actually be able to pull this off after all!</p>
<h3 id="friday-may-12th-weve-got-a-first-level">Friday, May 12th: We&rsquo;ve got a first level!</h3>
<p>After starting the day with a climbing session at the bouldering gym and some chatting with my buddies, I returned home, jumped into the shower and immediately got another idea for the game<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>: Modulating the bullet speed based on health, increasing their speed the less health you still have, leading to a more frantic feeling and also even more damage output.</p>
<p>As soon as I was done with the morning routine I sat back down in front of the laptop and looked into implementing that. It turned out to be surprisingly easy to do, and when I fired up the game for the first time and took some damage on purpose I actually loudly shouted &ldquo;F*CK YEAH!&rdquo; because it made the game feel so much better!</p>
<p>I spent the rest of the day implementing the first level - creating a bunch of enemies and made them follow the player, move in a pattern across the screen or just stay statically in place and shoot away, fine tuning placement and playing through it again and again and again until I was happy with the feeling of things. In the process, I also found and fixed a sheer ton of bugs and minor or major annoyances, including a couple of game breaking race conditions 😬</p>
<p>Somewhere during that day, <a href="https://foosel.itch.io/pew-pew-pew-danger-zone">I also set up the game on itch.io</a>, wrote a little description, created some preview images and made sure the web export was running fine. At this point the page was still set to private, but thanks to the shareable secret link I was already able to send it to a few friends for testing, which is what I did.</p>
<p>I think around this time I must also have added the highscore mechanism, incl. persistence, which to my happy surprise also worked without any issues in the web export.</p>
<p>By the end of the day, I was exhausted, but happy with the progress, right on time, and looking forward to the next day!</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110357894701554845">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p>Current state: exhausted, but level 1 designed through and implemented :D Only needs some more fine tuning! Also fixed a ton of issues I found during play testing, even some game breaking race conditions 😲</p><p>Fun addition: firing interval now inversely scales with health too - the closer to the death, the faster you fire. &quot;Less health, more bullets&quot; indeed.</p><p>Quite happy with the progress once again! Nothing planned the next two days but working on and finishing this 💪</p>
                
                    
                        
                    
                    <div class="toot-img-grid-0">
                    
                        
                    
                    </div>
                    
                    
                        
                            
                            <style>
                                .img-36a639af097046ce2f167f127b49bccd {
                                    aspect-ratio: 1280 / 720;
                                }
                            </style>
                            <div class="ctr toot-video-wrapper">
                                <video muted playsinline controls class="ctr toot-media-img img-36a639af097046ce2f167f127b49bccd">
                                    <source src="https://assets.chaos.social/media_attachments/files/110/357/880/597/878/877/original/e03754c6fe10d442.mp4">
                                    <p class="legal ctr">(Your browser doesn&rsquo;t support the <code>video</code> tag.)</p>
                                </video>
                            </div>
                        
                        
                    
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110357894701554845" class="toot-date" rel="noopener">May 12, 2023, 21:43</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<h3 id="saturday-may-13th-content-done">Saturday, May 13th: Content done!</h3>
<p>I woke up to some amazing feedback from a buddy and implemented that right away:</p>
<ul>
<li>the pickup gravity was a bit too aggressive and constantly yeeted things out of the screen, so I toned that down a bit and that help a lot</li>
<li>the drone was feeling too weak, so I increased its shot frequency</li>
<li>there was still an issue that the level end screen would not stop you from continuing to move around and shoot behind it - that required a bit more work, but was on the TODO list already anyhow</li>
</ul>
<p>Next task on the plan for the day was implementing two more levels and a boss! Since the boss definitely was the higher risk and higher impact, I tackled that one first, and created a big circle enemy chock full of hit points and with a shield powered by satellites rotating around it that would also shoot at the player. Admittedly that the shield was powered by these satellites was a bit of a hidden feature - shooting one down would temporarily remove the shield, only for it to return, until all satellites were taken out. It seems not many players might have caught on to that though 😅</p>
<p>I threw it into its dedicated level and added a boss health bar to the HUD.</p>
<p>Around afternoon I posted a sneak peak of the boss on Mastodon:</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110362364305310898">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p>👀</p>
                
                    
                        
                            
                        
                    
                    <div class="toot-img-grid-1">
                    
                        
                            
                            <style>
                                .img-a1495e23254a6b3d9ad23184fa599034 {
                                    aspect-ratio: 1280 / 720;
                                }
                            </style>
                            <img
                                src="https://assets.chaos.social/media_attachments/files/110/362/360/528/771/954/original/08beffe37c501cda.png"
                                alt="Screenshot of the boss in my game Pew Pew Pew: Danger Zone!

A big circular enemy, with five triangle shaped enemies orbiting it. Tons of bullets on the screen."
                                class="toot-media-img img-a1495e23254a6b3d9ad23184fa599034"
                                loading="lazy"
                            />
                        
                    
                    </div>
                    
                    
                        
                        
                    
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110362364305310898" class="toot-date" rel="noopener">May 13, 2023, 16:40</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<p>I then went on to create two more levels, which turned out to be surprisingly fast - I was able to reuse some of the enemy movement patterns and also could quickly implement some more ideas I had, thanks to the pluggable behaviours and Godot&rsquo;s animations.</p>
<p>The music selection was finalized as well: &ldquo;Screams in the Distance&rdquo; (as loop) from <a href="https://davidkbd.itch.io/eternity-metal-scfi-music-pack">DavidKBD&rsquo;s Eternity Pack</a> for the title screen, &ldquo;Spiral of Plasma&rdquo; for the levels and &ldquo;Synth Kobra&rdquo; for the boss fight, both from <a href="https://davidkbd.itch.io/interstellar-edm-metal-music-pack">DavidKBD&rsquo;s Interstellar Pack</a>.<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup></p>
<p>Doing test play after test play while developing I came to the conclusion that the boss encounter still needed a certain &ldquo;oompf!&rdquo; and added a warning animation with an alert sound, which together with the music choice imho really helped to set the right tone for a boss fight.</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/boss-fight.mp4" type="video/mp4">
  <span></span>
</video>
<p>After some more testing and fine tuning I decided to go public with the game, in the hopes to get some more feedback from a wider audience before the final day, <a href="https://foosel.itch.io/pew-pew-pew-danger-zone">published the itch.io page</a> and posted a link to it on Mastodon:</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110362764232694746">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p>Okay! As of now all the content I wanted to create for &quot;Pew Pew Pew: Danger Zone!&quot; has been created 🥰</p><p>For the rest of today and all of tomorrow the plan is testing, testing, testing, improving some things a bit and ironing out any kinks I find.</p><p>I&#39;m beyond proud that I so far actually did manage to pull this off the way I planned it, for my first jam ever. Feels amazing. 😄</p><p><a href="https://foosel.itch.io/pew-pew-pew-danger-zone" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">foosel.itch.io/pew-pew-pew-dan</span><span class="invisible">ger-zone</span></a></p><p><a href="https://chaos.social/tags/GoGodotJam4" class="mention hashtag" rel="tag">#<span>GoGodotJam4</span></a> <a href="https://chaos.social/tags/GoGodotJam" class="mention hashtag" rel="tag">#<span>GoGodotJam</span></a> <a href="https://chaos.social/tags/gamedev" class="mention hashtag" rel="tag">#<span>gamedev</span></a> <a href="https://chaos.social/tags/gamejam" class="mention hashtag" rel="tag">#<span>gamejam</span></a></p>
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110362764232694746" class="toot-date" rel="noopener">May 13, 2023, 18:22</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<p>At this point I also submitted it to the jam, knowing full well that it was not yet done, but also that I&rsquo;d still be able to upload new builds and update the page itself until the deadline. I figured I&rsquo;d rather have an old build submitted than miss the deadline altogether due to some unforeseen circumstances.</p>
<p>Then I continued testing and fixing stuff until I was too tired to do go on and went to bed.</p>
<h3 id="sunday-may-14th-day-of-the-deadline">Sunday, May 14th: Day of the Deadline!</h3>
<p>I woke up to some more feedback, one point of which would turn out to be the most common one during the rating phase as well: the enemy bullets were too hard to see. I tried changing their color to red like the enemies themselves, and that helped, but made the game look a bit too monochrome. So I decided to see if switching to a darker background would help, and it did indeed.</p>
<p><img alt="Screenshot of the boss fight in front of a darker background. The bullets have more contrast now." loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/boss-fight-darker.png"></p>
<p>Things were still not perfect, but it was the final day, I still had to implement a tutorial screen, do some more testing, fine tune some sound effects and finally do several more testing runs - I really didn&rsquo;t have time for big experiments anymore to make the bullets more visible. And to be honest, I didn&rsquo;t consider trying to completely avoid the enemy bullets the goal of the game anyhow, given getting hit was the only way to improve your damage output and there was some short period of invincibility after taking a hit, so sudden death scenarios shouldn&rsquo;t be that big of a concern either.</p>
<p>Thus, I put &ldquo;further research how to increase visibility of enemy bullets&rdquo; on the &ldquo;post jam&rdquo; task list and after redoing all the screenshots and going over all game items to make sure they still were visible too (the shield pickup needed some changes here), I tackled the tutorial. I had said goodbye to the idea of a tutorial level a long time ago already, and almost scratched the tutorial screen as well, but figured it would be better to have some hints in game. I created some key graphics to visualize the controls and put together a basic &ldquo;how to play&rdquo; one-pager that could be selected in the main menu. I also added a very basic keyboard control summary to the bottom of the screen right at the start of the first level, that would slowly fade out.</p>
<p><img alt="Screenshot of the final menu, with the new &ldquo;how to play&rdquo; option" loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/menu.png"></p>
<p><img alt="Screenshot of the tutorial screen" loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/tutorial-screen.png"></p>
<p><img alt="Screenshot of the control summary at the start of the first level" loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/control-summary.png"></p>
<p>What then followed were a couple more hours of final testing, and once I could no longer find anything crucial that needed to be fixed, I decided to call it done, did a final upload and announced on Mastodon that I was done:</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110367608340282718">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p>With the latest update that adds some final polishing (and after making another run through to make sure everything looks ok), I&#39;m calling a wrap on &quot;Pew Pew Pew: Danger Zone!&quot; and my first <a href="https://chaos.social/tags/gamejam" class="mention hashtag" rel="tag">#<span>gamejam</span></a> </p><p>Wow, what an experience. Woke up last Saturday to the theme, thought about it during my morning routine, came up with an idea &amp; put down a plan that felt doable in the available time. And - to my absolute surprise - this plan worked out! Beyond proud! 😊</p><p><a href="https://foosel.itch.io/pew-pew-pew-danger-zone" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">foosel.itch.io/pew-pew-pew-dan</span><span class="invisible">ger-zone</span></a></p>
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110367608340282718" class="toot-date" rel="noopener">May 14, 2023, 14:54</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<p>And if you want to see what the game looked like at the time of submission, here&rsquo;s a playthrough of the first level:</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/pewpewpew-level1.mp4" type="video/mp4">
  <span></span>
</video>
<p>and another one of the boss fight:</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/pewpewpew-boss.mp4" type="video/mp4">
  <span></span>
</video>
<h2 id="feedback--lessons-learned">Feedback &amp; lessons learned</h2>
<p>After the submission phase ended, what came next was the rating phase. Everyone who had submitted a game during the jam and of course the organizers themselves could now rate the submissions in five categories. Quoting from the jam page:</p>
<blockquote>
<ol>
<li><strong>Technical</strong> - Does the game work? Does the game show off the engine? Does it do anything particularly impressive? Is it feature rich?</li>
<li><strong>Artistic</strong> - Is it pretty? Are the sound and visuals effective and fitting? Is the style coherent to the gameplay? Are the text boxes legible?</li>
<li><strong>Design</strong> - Does the game teach you how to play it? Do the mechanics make sense?</li>
<li><strong>Gameplay</strong> - Is it fun? Does the difficulty scale? Are there accessibility options? Have I played the same game before or is it innovative?</li>
<li><strong>Theme</strong> - Does the game fit the theme? Is it surface level or is the theme at the core of the game?</li>
</ol>
</blockquote>
<p>It took me a while to wrap my head around these categories and get a good feeling for how to rate games in them, but after a couple games played and rated I got into a good groove. Meanwhile I started receiving comments and feedback from other participants and a recurring theme there was: &ldquo;the enemy bullets are hard to see&rdquo; 😅</p>
<p>Lesson learned: I should at least have given myself a timebox on that last day, to try out some more things to make the bullets more visible. I&rsquo;m still not sure if I would have found a solution that would have worked well, but some more timeboxed experimenting might have helped. But then, it was the final day of my first ever jam, and I was a bit anxious to get everything done in time, so I guess I can forgive myself for not having done that.</p>
<p>Other than that the feedback was very positive, and when <a href="https://youtu.be/fp_1nU3fvwA?t=4185">it even got streamed by one of the judges</a> I was happy to see that they seemed to really enjoy it and gave me some great ratings as well! Many people said it was fun, enjoyed the intensity, and gave amazing suggestions on how to improve it further.</p>
<p>I also got into some nice discussions about gamedev in general with other participants (and made at least one new friend 👋😊).</p>
<p>So, while horribly anxiety inducing whenever I saw a new notification pop up on itch.io, the rating phase was also a lot of fun, I learned a lot from it and got a ton of helpful feedback!</p>
<p>And I hope I did my part in making it a similarily positive experience for the others as well, by giving them constructive feedback on their games too. I tried to play and rate as many games as possible, and while I didn&rsquo;t manage to play all of them (there were almost 200 submissions!), I did play and rate 42 games in the end, which was almost double of the ratings that I received. Next time I&rsquo;ll try to do more!</p>
<h2 id="final-results--the-future-of-pppdz">Final results &amp; the future of PPP:DZ</h2>
<p>Rating ended late on May 25th, but the results would not be announced until a final event stream that got scheduled for late on May 27th.</p>
<p>In the end, I made 21st place overall in the jam, and even #9 in gameplay, which was an outcome that I absolutely did not expect on my first ever gamejame participation and only my second gamedev experience! When I saw the results, I was absolutely floored! Based on what I had seen from others during the jam, I was hoping I&rsquo;d made it in the Top 100 (out of almost 200 submissions), and would have already been happy with a placement in the Top 50. That I almost made it into the Top 20 and even managed to secure a place in the Top 10 of the Gameplay category was beyond my wildest dreams!</p>
<p><img alt="Screenshot of my final score, showing the overall placement at 21st place and Gameplay at 9th" loading="lazy" src="/blog/2023-05-30-developing-pew-pew-pew-danger-zone/result.png"></p>
<p>But even before this amazing outcome I had already decided that I wanted to continue working on the game. I found myself playing it again and again on my Steamdeck, trying to improve on my highscore, and that made me think that I had indeed something fun here that I could build on.</p>















        
        

        
            
            
        

        
            <blockquote class="toot-blockquote" cite="https://chaos.social@foosel/status/110369145946028083">
                <div class="toot-header">
                    <a class="toot-profile" href="https://chaos.social/@foosel" rel="noopener">
                        <img
                            src="https://assets.chaos.social/accounts/avatars/000/235/099/original/a2e381e9aab4a693.png"
                            alt="Mastodon avatar for @foosel@chaos.social"
                            loading="lazy"
                        />
                    </a>
                    <div class="toot-author">
                        <a class="toot-author-name" href="https://chaos.social/@foosel" rel="noopener">Gina Häußge</a>
                        <a class="toot-author-handle" href="https://chaos.social/@foosel" rel="noopener">@foosel@chaos.social</a>
                    </div>
                </div>
                <p>Y&#39;all, that is still just such an amazing feeling...</p><p>And I really enjoy playing this game that I built, so much so that I&#39;m thinking to build up on this concept further and ideas are starting to float around in my head 🤔 </p><p>We&#39;ll see 😁</p><p>Btw, I&#39;ve put the Linux export up on the itch.io page, so if you want to play it on the deck too, download, in desktop mode add as non-steam game, return to game mode, enjoy ^^ Left analog stick to move, A to shoot, X to trigger the bomb.</p>
                
                    
                        
                            
                        
                    
                    <div class="toot-img-grid-1">
                    
                        
                            
                            <style>
                                .img-920c0a88c11c58fef8bf59f5ba745990 {
                                    aspect-ratio: 1663 / 1247;
                                }
                            </style>
                            <img
                                src="https://assets.chaos.social/media_attachments/files/110/369/136/717/327/637/original/f2c5a715125cd903.jpg"
                                alt="My game running on my Steamdeck "
                                class="toot-media-img img-920c0a88c11c58fef8bf59f5ba745990"
                                loading="lazy"
                            />
                        
                    
                    </div>
                    
                    
                        
                        
                    
                
                
                
                <div class="toot-footer">
                    <a href="https://chaos.social/@foosel/110369145946028083" class="toot-date" rel="noopener">May 14, 2023, 21:25</a>&nbsp;<span class="pokey">(UTC)</span>
                </div>
            </blockquote>
        
    
<p>So - I won&rsquo;t let myself get nailed down on &ldquo;when&rdquo; here (day job, balance, etc), but my plan is to take this concept and develop it further into a full game. I already have a couple of ideas on how to do that, and I&rsquo;m looking forward to working on them.</p>
<p>And what about future gamejam participations? I&rsquo;m hooked now and plan to participate next in the <a href="https://itch.io/jam/gmtk-2023">GMTK Game Jam 2023</a> in July. That will be probably be a solo effort again, and way more intense given that I&rsquo;ll have to take a game from idea to finished product in 48 hours, but I&rsquo;m looking forward to the challenge!</p>
<h2 id="play-the-game">Play the game!</h2>
<p>If you want to play the game, you can find it on itch.io here:</p>



<iframe style="margin: 1em auto" src="https://itch.io/embed/2063488?dark=true" width="552" height="167" frameborder="0"></iframe>

<p>And I&rsquo;ve also thrown up the sources on GitHub: <a href="https://github.com/foosel/pew-pew-pew-danger-zone">foosel/pew-pew-pew-danger-zone</a><sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>. Just a word of warning on those: I&rsquo;m by no means an expert in Godot Engine, and a gamedev newbiew, and I was developing under heavy time constraints. I might have done some horrible things, please don&rsquo;t hold them against me 😅</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Yes, indeed, it was an actual shower thought.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>I plan to attend <a href="https://entropia.de/GPN21">GPN21</a> next week and wanted to get another booster shot before that just in case - as much as everyone seems to pretend it is, no, COVID is not over, and the last thing that I need in my extremely stressful and busy life is to get sick, possibly even long term.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>Admittedly, getting up really early to get an hour in at the bouldering gym before work like every Tuesday didn&rsquo;t help either 😬&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>I you see a pattern emerging here that involves me getting great ideas in the shower, you are not wrong. OctoPrint might also have been one, but ten years later I frankly can&rsquo;t remember for sure. At this point however I keep a stack of waterproof post-its and a pencil in the shower, in case something good pop ups in my head.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>If you are looking for some metal riffs for your game, take a look at <a href="https://davidkbd.itch.io">David&rsquo;s work</a>, it&rsquo;s really good!&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>You are welcome to dig around in the code and also of course to send in PRs, but I&rsquo;m currently still debating with myself if I want to merge anything from others, so please don&rsquo;t get offended if any PRs stay open and also uncommented for now 😅&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How to export a Godot 4 game to run on the web on itch.io</title><link>https://foosel.net/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/</link><pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate><guid>https://foosel.net/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/</guid><description>&lt;p&gt;On the &lt;a href="https://itch.io/jam/go-godot-jam-4"&gt;Go Godot Jam 4&lt;/a&gt; Discord I just saw some people having issues with how to get HTML5 exports from Godot 4 to work on itch.io, and since I just had to do this for &lt;a href="https://foosel.itch.io/pew-pew-pew-danger-zone"&gt;my own game submission to the jam&lt;/a&gt; as well I decided to jot my steps down here (and on the Discord too) as it seems to be a bit of a pain for people.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First of all export your game using the &amp;ldquo;Web&amp;rdquo; export template&lt;/p&gt;</description><content:encoded><![CDATA[<p>On the <a href="https://itch.io/jam/go-godot-jam-4">Go Godot Jam 4</a> Discord I just saw some people having issues with how to get HTML5 exports from Godot 4 to work on itch.io, and since I just had to do this for <a href="https://foosel.itch.io/pew-pew-pew-danger-zone">my own game submission to the jam</a> as well I decided to jot my steps down here (and on the Discord too) as it seems to be a bit of a pain for people.</p>
<ol>
<li>
<p>First of all export your game using the &ldquo;Web&rdquo; export template</p>
<p><img alt="The export dialog of the Godot Engine 4 editor with the Web export template selected" loading="lazy" src="/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/export.png"></p>
</li>
<li>
<p>Navigate to your export folder, make sure to rename your <code>.html</code> file to <code>index.html</code></p>
</li>
<li>
<p>Zip all of it up, with all the files right within the root of the zip file</p>
<p><img alt="The contents of the created zip file, the html file has been renamed to index.html, all files are in the zip&rsquo;s root" loading="lazy" src="/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/zip.png"></p>
</li>
<li>
<p>Upload to itch, make sure to check &ldquo;This file will be played in the browser&rdquo;</p>
<p><img alt="itch.io&rsquo;s upload dialog, the mentioned option is checked next to the zip upload" loading="lazy" src="/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/upload.png"></p>
</li>
<li>
<p>Scroll down to &ldquo;Embed Options&rdquo; and make sure &ldquo;<code>SharedArrayBuffer</code> support&rdquo; is checked</p>
<p><img alt="The mentioned embed options, &ldquo;Shared Array Buffer support&rdquo; is checked" loading="lazy" src="/til/how-to-export-a-godot-4-game-to-run-on-the-web-on-itchio/embed_options.png"></p>
</li>
</ol>
]]></content:encoded></item><item><title>The path to Super Bunny Hoppers</title><link>https://foosel.net/blog/2023-04-16-the-path-to-super-bunny-hoppers/</link><pubDate>Sun, 16 Apr 2023 00:00:00 +0000</pubDate><guid>https://foosel.net/blog/2023-04-16-the-path-to-super-bunny-hoppers/</guid><description>A report on an amazingly thoughtful gift and how it made me spent my Easter holiday with cute bunnies jumping on top of garden gnomes</description><content:encoded><![CDATA[<p>For my 40th birthday a few weeks ago, I got a pretty amazing gift from my partner: a coupon for a personal 4-day Gamejam/Gamedev experience, just the two of us.</p>
<p><img alt="A coupon saying &ldquo;Make and save your date for 4 days of Make Your Own Gamejam with Godot Game Engine&rdquo;" loading="lazy" src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/gamejam-coupon.jpg"></p>
<p>I&rsquo;ve been a gamer pretty much my whole life, I&rsquo;ve been a coder pretty much my whole life, but I never so far managed to combine these things. Apart from copying some Star Trek game code in BASIC from a book in my teens, the probably quite common tinkering around with the parameters in <a href="https://en.wikipedia.org/wiki/Gorillas_(video_game)"><code>gorilla.bas</code></a>, and a Snake clone in <a href="https://www.opengl.org/resources/libraries/glut/glut_downloads.php">GLUT</a> in preparation for a 3d graphics course in university, I never so far got into game development. It has been something high on my bucket list however, and I&rsquo;ve been fascinated by the concept of gamejams like <a href="https://ldjam.com/">Ludum Dare</a>, <a href="https://gmtk.itch.io/">GMTK Jam</a> etc., where you build a game matching a provided topic within a set time limit (usually between two to ten days) and within a set of rules (e.g. do you need to do everything yourself, including graphics and music, or are you allowed to use certain existing assets, do you need to use a specific game engine etc). Add to that the fact that these days I&rsquo;m way more into playing indie games than the AAA stuff from the big players<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, a love for learning new stuff and the release of the latest major version 4 of the fully open source <a href="https://godotengine.org/">Godot Engine</a> that has made me curious for a while now, and you might see why this really WAS an absolutely amazing gift by my partner.</p>
<p>We did this event from April 5th to 8th (and I kept a <a href="https://chaos.social/@foosel/110145537112426679">Mastodon thread</a> going throughout it). The first two days were a crash course in Godot Engine for me and in pixel art creation for him. The last two days were spent on creating a full (albeit short) platformer game from scratch.</p>
<h2 id="day-1">Day 1</h2>
<p>The first day was dedicated to getting to know the Godot IDE, going through the <a href="https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html">2d game tutorial</a> and then further experimenting with whatever tickled our fancy.</p>
<p>I quickly went through the tutorial and soon had some first results to show for it. In the end, I even managed to get a &ldquo;Dodge the Creeps&rdquo; build exported for Linux and up and running on my Steamdeck, which was a very rewarding outcome indeed! I can&rsquo;t say that I ever found it THAT easy to get Homebrew to run on any of my consoles as it was with the Steamdeck - <code>scp</code> the binary over, add to Steam as external game, done 😊</p>
<p><img alt="Me, holding up my Steamdeck with a big grin and pointing to the screen, which is showing the &ldquo;Dodge the Creeps&rdquo; game I just got to run on it." loading="lazy" src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/happy-foosel.jpg"></p>
<p>Still, as you can see, I was quite happy about that!</p>
<p>I also added some very basic sound effects to the game, which was not very tricky to achieve but had a great effect on the overall polish of that simple first try.</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/dodge-the-creeps.webm" type="video/webm">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/dodge-the-creeps.mp4" type="video/mp4">
  <span></span>
</video>
<p>Next - while my partner was making a deep dive into some pixel art courses - I decided to play around a bit with the physics engine, particle system, sound effects etc by building a small Asteroid-like playground thingy that consisted of just one screen with a little player controlled <a href="https://www.kenney.nl/assets/pixel-shmup">space ship</a>, <a href="https://faktory.itch.io/pixel-planets">two small planets</a> that the spaceship could shoot at (doubtlessly a morally highly questionable mechanic) and some wrap-around behaviour.</p>
<p>At some point, my bullet spawning code was broken, making my ship lay eggs, which nicely fit the fact that we were doing this event over the Easter holidays 😉</p>
<video controls preload="auto" width="100%"  autoplay loop playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/physics-experiments-bug.webm" type="video/webm">
  <span></span>
</video>
<p>Originally I also wanted to have the planets excert gravity on the ship and the bullets, and initially that did work, but at some point it stopped working. I still haven&rsquo;t figured out why 😅 I ended the first day with pew-pew-pew.</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/physics-experiments.webm" type="video/webm">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/physics-experiments.mp4" type="video/mp4">
  <span></span>
</video>
<h2 id="day-2">Day 2</h2>
<p>For the second day, we had planned creating two simple prototypes, one Pong like game and one basic platformer.</p>
<p>We started with the Pong like game and agreed on a slightly futuristic but pixel based graphics style and the name &ldquo;Neon Pong&rdquo;. As my partner was still working through some more pixel art courses I started with some basic placeholder graphics (white rectangles ftw). My idea was to use <a href="https://docs.godotengine.org/en/stable/tutorials/physics/index.html">Godot&rsquo;s physics engine</a>, and my first implementation attempt led to yet another hilarious bug:</p>
<video controls preload="auto" width="100%"  autoplay loop playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/neon-pong-bug.webm" type="video/webm">
  <span></span>
</video>
<p>After ironing that out, I got some simple two player controls implemented, as well as a slightly randomised spawning angle for the ball, scoring and win and lose detection. That involved figuring out how to detect when the ball goes out of bounds (which I already had learned during the tutorial: <a href="https://docs.godotengine.org/en/4.0/classes/class_visibleonscreennotifier2d.html"><code>VisibleOnScreenNotifier2D</code></a>) and some other stuff. I also added some sound effects for the ball bouncing off of obstacles, courtesy of <a href="https://www.drpetter.se/project_sfxr.html">sfxr</a> and some light effects that turned out to be less visible than I had hoped for.</p>
<p>At some point my partner sent me some assets to use for the paddles, the ball, the walls and the background and I also picked out <a href="https://opengameart.org/content/flux-capacitor-no-marty">a nice CC0 synthwave song called &ldquo;Flux Capacitor&rdquo; by &ldquo;Frenchyboy&rdquo;</a>, combined everything, and we had our basic Pong prototype:</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/neon-pong.webm" type="video/webm">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/neon-pong.mp4" type="video/mp4">
  <span></span>
</video>
<p>At that point my partner communicated that he&rsquo;d be quite busy for yet a while to come with the pixel art course, so we decided on me just grabbing some more ready-made assets for the platformer prototype to experiment a bit with the mechanics we&rsquo;d need for the coming days. So I got <a href="https://egordorichev.itch.io/adve">a neat 8x8px dungeon tileset</a> and also treated myself to some <a href="https://egordorichev.itch.io/chare">8x8 animated characters by the same author</a> and started building. First of all I learned how to use Godot&rsquo;s <a href="https://docs.godotengine.org/en/stable/tutorials/2d/using_tilesets.html">tileset feature</a>, so I wouldn&rsquo;t have to manually place each individual tile but rather got just draw full rectangles and such. After that was done I created a very basic single-screen dungeon and a player character. I once again turned to the physics engine to do the heavy lifting, set up collisions, jumping, and also - since the tiles I used came with some wooden platforms - figured out how to make the character fall through those on a press on the down key (hint: manually increasing the y position by 1, negating the collision). Then I added some basic light to the torches I had placed and created some basic enemies and their pathing. For that I had to figure out how to keep them from falling off of platforms but instead switching directions on collisions with walls or cliffs (for the walls, the physics engine already helped, but for the cliff detection I had to learn how to use <a href="https://docs.godotengine.org/en/stable/classes/class_raycast2d.html"><code>Raycast2D</code> nodes</a>).</p>
<p>I didn&rsquo;t manage to implement a proper jump-on-top-the-enemy-to-kill-them mechanic as it was growing quite late already (and we had set ourselves fixed hours to not overdo it), but that led to yet another fun little bug with my character riding on top of a pathing enemy which gave me a good laugh at the end of day 2:</p>
<video controls preload="auto" width="100%"  autoplay loop playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/yap-yap-yap.webm" type="video/webm">
  <span></span>
</video>
<h2 id="day-3">Day 3</h2>
<p>The third day started at the climbing gym, but right after that we got started on our opus magnum for this event: our little platformer. The idea was to build something heavily inspired by Super Mario, but with cute little bunnies hunting carrots and easter eggs - a wish by one of my partner&rsquo;s colleagues. For enemies, I had the idea to add some invading garden gnomes into the mix. We settled on a tilesize (16x16px), some basic mechanics (two selectable characters, jump on enemies, progress through level from left to right, have some predefined checkpoints that act as respawn points upon death, two hit points, &hellip;). While my partner was still working through the final parts of his pixel art course<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, after getting my hands on some <a href="https://v3x3d.itch.io/retro-lines">placeholder assets</a> I started coding.</p>
<p>This time I started with the player. In order to be able to make the code a bit cleaner and more modular, I decided on implementing a state machine for it, and defined states for &ldquo;idle&rdquo;, &ldquo;walking&rdquo;, &ldquo;jumping&rdquo; and &ldquo;falling&rdquo;, and later also added &ldquo;spawned&rdquo; and &ldquo;hit&rdquo;. The states took care of parsing the possible inputs, triggering animations and sound effects and so on, and having that nicely packaged up into each individual state turned out to make the logic WAY easier to implement. I also added a configurable sprite set slot, in order to support multiple player skins and thus characters.</p>
<p>For the enemies, I implemented a parent scene with physics and pathing (once again the wall and cliff detection with direction change), configurable sprites and score. I learned how to scene inheritence and created two enemy types.</p>
<p>Next came the biggest challenge. Since we wanted to have at least two levels (spoiler alert: we only made two levels), I needed a way to dynamically load a level, spawn enemies etc. I didn&rsquo;t want to hard code everything per level and have code repetition, so instead I build a modular level loader. Levels are individual scenes with a tilemap node as the root node that defines the level tiles. Below that node, a specially named <a href="https://docs.godotengine.org/en/stable/classes/class_marker2d.html"><code>Marker2D</code></a> node defines the player spawn, a flexible number of <code>Marker2D</code> nodes assigned to the <code>enemies</code> group act as enemy spawns. A special checkpoint scene was implemented with an <a href="https://docs.godotengine.org/en/stable/tutorials/physics/using_area_2d.html"><code>Area2D</code></a> and a custom <code>checkpoint_reached</code> signal, and some code was added to make sure the last reached checkpoint per level would act as spawnpoint. Instances of this checkpoint scene can then be placed in the level. Finally, a special level exit scene listens for collisions with the players and signals level completion, and another <code>Marker2D</code> level end marker sets the limits of the camera.</p>
<p><img alt="A screenshot from Godot Engine, showing a level scene with the aforementioned additional nodes below the tilemap" loading="lazy" src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/sbh-level-design.png"></p>
<p>To load a level now, the loader would get the name of the level scene to load, instantiate it and insert it into the tree, then fetch the player and enemy spawns and populate them, and also wire up all the required signals. That worked so well that I quickly created two basic test scenes, threw them into an array and wired up the level exit to unloading the current level and loading the next from the array.</p>
<p>The rest of the day was spent further refining the gameplay and fixing bugs in the quickly threwn together dummy level and then starting on the main menu and the character selection screen, and getting some glimpses here and there at the amazing assets my partner was busy working on<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> 😊</p>
<h2 id="day-4">Day 4</h2>
<p>The fourth and final day started with me continuing on the menu and getting it to work 🥳 I then also implemented a pause menu, credits (that would load and roll after reaching the final level exit, and loop back to the main menu), a game over screen and while doing all of that also got back again and again to the gameplay itself, ironing out bugs as I went.</p>
<p>Some time before noon, I started getting the first asset dumps from my partner and the integration started. The first assets I got where the character and enemy assets, and I created spritesets from all of them and wired them up correctly. At that point I also slightly changed the player character&rsquo;s animation behaviours, so that when the player would switch to falling after jumping, the animation would also switch from a jumping to a falling bunny. Ridiculously small effect, but it somehow tied everything a bit together in my humble opinion.</p>
<p>The game was still completely silent, so I sat down with sfxr again and created sound effects for jumping, the player getting hurt &amp; dying, an enemy getting killed, collecting a carrot and collecting an egg. That kept me busy until my partner dropped the tilesets into our shared folder.</p>
<p>I then figured out <a href="https://foosel.net/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/">how to animate tilemap items</a> for the collectable carrots and easter eggs, and then drew up and populated the actual levels from two templates my partner had created, heavily based on the first two levels of Super Mario Bros. Thanks to day 3&rsquo;s work on the dynamic level loading that was a <em>breeze</em> and my partner seemed quite amazed at how fast I got this done ^^.</p>
<p>We decided that there definitely was not enough time left to create music from scratch as well (it was already getting dark and our personal cut off time was drawing close), so instead I went hunting for some nice chiptunes and with <a href="https://tallbeard.itch.io/three-red-hearts-prepare-to-dev">&ldquo;Three Red Hearts&rdquo;</a> found some amazing ones courtesy of <a href="https://abstractionmusic.com">Abstraction</a>. We decided on four tracks (main menu, level 1, level 2, credits), I threw everything together and some final testing and debugging later we had our first game 😊</p>
<p>And this is it, <strong>Super Bunny Hoppers</strong>:</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/super-bunny-hoppers.webm" type="video/webm">
    <source src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/super-bunny-hoppers.mp4" type="video/mp4">
  <span></span>
</video>
<h2 id="the-days-after">The days after</h2>
<p>We had to take a break the next day since these four days were quite intense, but two days later after some pleas on Mastodon to put up the game up somewhere, I polished things up slightly (by e.g. making the game be controller and fully keyboard playable) and - thanks to Godot&rsquo;s HTML5 export - quite quickly threw it up on <a href="https://foosel.itch.io/super-bunny-hoppers">foosel.itch.io</a> where you can now play it yourself in all its glory!</p>
<p><img alt="Screenshot of the linked itch.io page, showing the embedded game" loading="lazy" src="/blog/2023-04-16-the-path-to-super-bunny-hoppers/itch-io.png"></p>
<p>All in all, I had an absolute blast during these four days (which I&rsquo;ve also told my partner repeatedly), and so did my partner. I see the one or other actual gamejam participation in mine and his future now - I&rsquo;m currently planning to attend the upcoming <a href="https://gogodotjam.com/">Go Godot Jam</a>, though he probably won&rsquo;t be able to thanks to a colliding work event - and am currently spending way too much time soaking up gamedev content on YouTube, am making my way through Scott Rogers&rsquo; &ldquo;Level Up! The Guide to great video game design&rdquo; (another amazing birthday gift by my partner), have started a backlog of game ideas and experiments I want to look into implementing and overall feel quite confident now that I <em>can</em> in fact create games - I just have to do it 😊</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I prefer creative game mechanics and new ideas over the 24th installation of &ldquo;shoot the bad guys with ultra realistic graphics and a licensed soundtrack&rdquo; or any such franchise - especially since said graphics often give me severe motion sickness.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>It was a long one, but it definitely paid off in my opinion 😊&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>And which I&rsquo;ve since <a href="https://chaos.social/@foosel/110198016865272377">turned into custom coasters for him</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item><item><title>How to create an animated tile in Godot 4's tilemaps</title><link>https://foosel.net/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/</link><pubDate>Sun, 09 Apr 2023 00:00:00 +0000</pubDate><guid>https://foosel.net/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/</guid><description>&lt;p&gt;Over the past four days I&amp;rsquo;ve been doing &lt;a href="https://chaos.social/@foosel/110145537112426679"&gt;a personal crash course on game development&lt;/a&gt; together with my partner&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;, ending up in building &lt;a href="https://chaos.social/@foosel/110165066201016720"&gt;a small platformer in two days&lt;/a&gt;. We decided to use &lt;a href="https://godotengine.org"&gt;Godot Engine&lt;/a&gt;, as I had been circling it for a while now &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;, and it turned out this decision was good because it was been a quite amazing experience, even for a total gamedev beginner like me 👍&lt;/p&gt;
&lt;p&gt;What cost me a bunch of time however is trying to figure out how to create an animated tile in a &lt;a href="https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html"&gt;tilemap&lt;/a&gt;, which I finally figured out yesterday, and so I&amp;rsquo;m writing it down here for future me and everyone else wondering about this.&lt;/p&gt;</description><content:encoded><![CDATA[<p>Over the past four days I&rsquo;ve been doing <a href="https://chaos.social/@foosel/110145537112426679">a personal crash course on game development</a> together with my partner<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, ending up in building <a href="https://chaos.social/@foosel/110165066201016720">a small platformer in two days</a>. We decided to use <a href="https://godotengine.org">Godot Engine</a>, as I had been circling it for a while now <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, and it turned out this decision was good because it was been a quite amazing experience, even for a total gamedev beginner like me 👍</p>
<p>What cost me a bunch of time however is trying to figure out how to create an animated tile in a <a href="https://docs.godotengine.org/en/stable/tutorials/2d/using_tilemaps.html">tilemap</a>, which I finally figured out yesterday, and so I&rsquo;m writing it down here for future me and everyone else wondering about this.</p>
<p>First of all, you need a graphic of your tile-to-be-animated. It should have all frames side by side, like this example:</p>
<p><img alt="Screenshot of a png, 64x16px in size, with four frames of a cartoonish floating carrot" loading="lazy" src="/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/step1.png"></p>
<p>This is going to become a floating 16x16px carot, its animation consisting of four frames.</p>
<p>Add it to a tileset by dragging the resource into the left column, and make sure that <em>only the first frame</em> becomes part of your tileset! If you have let automatic atlas tooling do its thing, <em>delete</em> the other frames again under &ldquo;Setup&rdquo;:</p>
<p><img alt="Screenshot of Godot 4&rsquo;s tileset editor, showing the freshly added carrot, deleting wrongly added tiles" loading="lazy" src="/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/step2.png"></p>
<p>Then switch to the tileset editor&rsquo;s &ldquo;Select&rdquo; panel and click on the first frame of your animation. On the left you&rsquo;ll see some options for that tile. Open &ldquo;Animation&rdquo;, then increase the number of animation frames to the number of your available frames (4 for our carrot here), and after that make sure to click on &ldquo;Add Frame&rdquo; once for each of your frames. You then can also define how long the frame will be shown, 1s by default. 0.3s will result in something like 10fps.</p>
<p><img alt="Screenshot of Godot 4&rsquo;s tileset editor, showing the final animation setup on the &ldquo;Select&rdquo; panel as described in the text" loading="lazy" src="/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/step3.png"></p>
<p>After that, placing the <em>first frame</em> in a tilemap should show it being animated now:</p>
<video controls preload="auto" width="100%"  playsinline class="html-video">
    <source src="/til/how-to-create-an-animated-tile-in-godot-4s-tilemaps/step4.webm" type="video/webm">
  <span></span>
</video>
<p>🥳</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Him focusing on pixel art, me on the coding bits.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Not only because it&rsquo;s also open source, though that also plays a big part!&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded></item></channel></rss>