<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://chadpluspl.us/feed.xml" rel="self" type="application/atom+xml" /><link href="http://chadpluspl.us/" rel="alternate" type="text/html" /><updated>2026-04-18T21:27:10+00:00</updated><id>http://chadpluspl.us/feed.xml</id><title type="html">Chad++</title><subtitle>My name is Chad Stewart. I make games.</subtitle><entry><title type="html">Postmortem: Deeper</title><link href="http://chadpluspl.us/blog/postmortem/2025/03/17/deeper-postmortem.html" rel="alternate" type="text/html" title="Postmortem: Deeper" /><published>2025-03-17T20:22:03+00:00</published><updated>2025-03-17T20:22:03+00:00</updated><id>http://chadpluspl.us/blog/postmortem/2025/03/17/deeper-postmortem</id><content type="html" xml:base="http://chadpluspl.us/blog/postmortem/2025/03/17/deeper-postmortem.html"><![CDATA[<p>Deeper is my second game for <a href="http://www.tinymassgames.com">Tiny Mass Games</a> as well as my second project in Godot and my second time using my phone to make a game. It is an action-esque, turn-based, extraction RPG. It is a GameBoy aesthetic party-based battle system with time bars instead of mana.</p>

<h3 id="features">Features</h3>

<ul>
  <li>An Extraction RPG that fits the GameBoy aesthetic and control limitations.
    <ul>
      <li>Control up to four characters at the same time, each with six different moves, using only left / right and A / B!</li>
    </ul>
  </li>
  <li>Fight 9 Common Enemies and 3 Unique Bosses, each with their own unique mechanics.</li>
  <li>Collect 50+ pieces of procedurally generated equipment and outfit your party.
    <ul>
      <li>Be careful! If characters die, their bodies and, more importantly, their loot are lost to the dungeon.</li>
      <li>(Collect unique equipment that can only be found once.)</li>
      <li>Unlock new color palettes to spice up later runs.</li>
    </ul>
  </li>
</ul>

<p><a href="https://binarysolo.itch.io/deeper">You can play the game on itch.</a></p>

<p>I originally intended for this game to be a smaller piece of a larger thing, but ended up not completing the larger thing.</p>

<h2 id="what-did-i-do-on-my-phone">What Did I Do On My Phone</h2>

<p>I started this game on my computer with a plan to do certain features or types of work on my phone: Tasks without audio, easy systems that didn’t require too much debugging, or better yet, creating Resources and doing basic data entry. That got thrown for a giant loop when my house was flooded and I lost said computer. (And the walls, stairs, washing machine, water heater, files, and more. Big things to lose, but away they went!)</p>

<p><img src="/assets/resources/posts/deeper/flood.jpg" alt="A basement flooded with 18 inches of standing, brown water." /></p>

<ul>
  <li>This game was entirely pixel art, so again I was able to use Pixel Studio Pro to create all of the graphics. This includes:
    <ul>
      <li>6 Hero Designs (Simple back of head only)</li>
      <li>6 Enemy Designs, 3 of which having 3 color variations.</li>
      <li>VFX</li>
      <li>Equipment Icons</li>
      <li>UI</li>
      <li>Logos</li>
    </ul>
  </li>
  <li>Created all equipment resources, both code and the data files.</li>
  <li>Created a virtual GameBoy wrapper that is only available on an Android device. On Android the game is forced into portrait and the controls all sit just below the fold, so to speak, on a regular windowed build.</li>
</ul>

<h2 id="what-i-did-on-a-computer">What I Did On a Computer</h2>

<p>I knew going into this one that I would have to make builds on desktop. I was going to aschew FMOD for this one since I knew the plugin didn’t load on an Android device. My plan this time was to do all of the system code on my desktop and then use my phone to just enter gobs and gobs of data.</p>

<p>Luckily I had a laptop I could do builds on, but everything else was via phone.</p>

<h2 id="what-i-learned">What I Learned</h2>

<ol>
  <li>
    <h3 id="godot-shaders">Godot Shaders</h3>
    <p>Not sure this is a full blown learning. Honestly, I think learning shaders is an evergreen process. You can tinker, you can do tutorials, you can learn the math. Always there’s new techniques, new pieces. For my purposes, what I learned was how to use Godot to write a shader. I already understood the basics of shaders, and I’ve used GLSL before. In this case, the shader was for the colorization of the GameBoy sprites.</p>

    <p>In order to get four shades of green, I started by setting up a gray-scale color swatch for my pixel art. All of the art in the game is drawn in grayscale using four colors. Then, I wrote a shader to take four defined colors (the shades of green), find the nearest, and render that instead. Here are the characters I created for the game.</p>

    <p><em>Warning: What you are about to see is programmer art. It may scare some viewers. Proceed at your own risk.</em></p>

    <div class="centered" style="text-align: center;">
   <img alt="Boy 1, back of head, " src="/assets/resources/posts/deeper/Boy0.png" /> <img alt="Boy 2, back of head," src="/assets/resources/posts/deeper/Boy1.png" /> <img alt="Boy 3, back of head, " src="/assets/resources/posts/deeper/Boy2.png" /> <img alt="Girl 1, back of head, " src="/assets/resources/posts/deeper/Girl0.png" /> <img alt="Girl 2, back of head, " src="/assets/resources/posts/deeper/Girl1.png" /> <img alt="Girl 3, back of head" src="/assets/resources/posts/deeper/Girl2.png" />
 </div>

    <p>And here is what characters look like in game:</p>

    <p><img src="/assets/resources/posts/deeper/deeper-cover.png" alt="Cover image for Deeper, title with enemy and four characters." class="centered" style="width: 144px;" /></p>

    <p>This is also the same magic which allowed me to implement palettes. By making those four colors shader parameters, I could change them at runtime thusly:</p>

    <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">var</span> <span class="n">colors_as_vectors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">colors_as_vectors</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">Vector3</span><span class="p">(</span><span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">r</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">g</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">b</span><span class="p">))</span>
<span class="n">colors_as_vectors</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">Vector3</span><span class="p">(</span><span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">r</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">g</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">b</span><span class="p">))</span>
<span class="n">colors_as_vectors</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">Vector3</span><span class="p">(</span><span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">r</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">g</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">b</span><span class="p">))</span>
<span class="n">colors_as_vectors</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">Vector3</span><span class="p">(</span><span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">r</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">g</span><span class="p">,</span> <span class="n">palette</span><span class="p">.</span><span class="n">colors</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">b</span><span class="p">))</span>
<span class="n">material</span><span class="p">.</span><span class="n">set_shader_parameter</span><span class="p">(</span><span class="s">"colors"</span><span class="p">,</span> <span class="n">colors_as_vectors</span><span class="p">)</span>
</code></pre></div>    </div>

    <p>(And because I could change them at runtime, you can actually choose what you want your palette to be!)</p>
  </li>
  <li>
    <h3 id="the-theme-and-style-settings">The Theme and Style Settings</h3>
    <p>Using Control nodes for your game, you can make a pretty powerful UI using Godot. As with any engine, there are things you’ll love, and things you’ll dislike.</p>

    <p>What I loved? The ease of setting up the UI. For more straightforward UIs it is a breeze. Once you need Layouts and Containers, then it gets a little tricky to make all the sizes work. Still, that’s merely a learning curve. I made the entire game using Control nodes, because I thought it would give me easier resolution scaling. (And I think it did in the end!)</p>

    <p>This did make positioning things when trying to do VFX a little awkward. Control nodes rely heavily on the heirarchy in the Scene Tree. This means there are some rules about parenting sprites that mean you can’t just lerp from hero to enemy. Those were mostly easy to work out, but sometimes required some thought.</p>

    <p>However, when it came to the Settings menu, to make it look all cool and on-brand for a pixelated GameBoy game, there was a boar of a task in setting up the Style via the Theme system. I figured it out, but it is a pain in the butt to parse what does what and how to achieve the look you want. Surely, with time, this might be less hard. For this project, it was pulling teeth.</p>
  </li>
  <li>
    <h3 id="the-built-in-audio-system">The Built-In Audio System</h3>
    <p>Last time I used FMOD and my audio extraordinairre, Garrett, handled everything on the FMOD side. This time, I knew I didn’t want to use FMOD because I wanted to get the full experience on mobile. I ended up picking up <a href="https://joelsteudler.itch.io/8-bit-action-music-sfx">a music pack from Joel Steudler</a> and doing the implementation myself. I liked the music, but I knew that it didn’t quite fit with the vibe I was trying to achieve.</p>

    <p>What I ended up doing was using the built in Audio players and using the Pitch Scale to change the feeling of the music. For example, here is the song I started with for the menu.</p>

    <audio controls="">
   <source src="/assets/resources/posts/deeper/Action_-_Dystopian_Opening.wav" type="audio/wav" />
   <source src="/assets/resources/posts/deeper/Action_-_Dystopian_Opening.ogg" type="audio/ogg" />
   Your browser does not support the audio element.
 </audio>

    <p>But when it gets Chopped and Screwed:</p>

    <video muted="" controls="">
   <source src="/assets/resources/posts/deeper/DeeperMenuChoppedAndScrewed.mp4" type="video/mp4" />
 </video>
  </li>
</ol>

<h2 id="what-worked">What Worked</h2>

<ol>
  <li>
    <h3 id="imaginary-equipment">Imaginary Equipment.</h3>
    <p>Set myself up for success by making things that could be pure data without art. Equipment, for example, only had an icon for it’s type. Not even any kind of sub-typing. We had a sword for any weapon. A shield for armor and accessories. (Because I made them all armor-ish sounding accessories like boots!)</p>

    <p>This meant I could just blast that type of content all day, which was good because the game is about loot. There were 22 pieces of equipment, basically for free.</p>
  </li>
  <li>
    <h3 id="all-about-status">All About Status</h3>
    <p>Let me let you in on a dirty little secret.</p>

    <p>…</p>

    <p>Everything is a status effect. Each enemy has some sort of unique twist on how you should deal with them. I wanted to encourage people to use their big, powerful attacks on slimes so if you hit them they deal 1 damage to the attacker. I wanted vampires to suck your blood so they restore health when they attack. I wanted a mob of bats to have as many HP as there were bats in the flock. (IE: If there were 8 bats on screen, you had to hit them 8 times.)</p>

    <p>Every single one of those things was done via the status effect system.</p>

    <p>At first I was going to program those all out with the AI that I had made. (And I still made complex-ish AIs.) But quickly I realized that every single behavior I had planned out would need the exact same hooks as my status effect system had. So then I just went whole hog on it. All I had to do was create an array on the Enemy Resource that contains “Innate Status Effects”. These would be applied on battle start and make it so that enemies can all do cool things.</p>

    <p>The slime had a “Reflect Damage” status effect that onAttacked would deal 1 damage to the attacker. The vampire had a “Vampire” status effects that would heal X% (to be defined by any instance of “Vampire”) whenever onAttack was called. You’ll never guess how those bats did it.</p>

    <p>Oh, wait, unless you’ve been paying attention. Yes, the bats had a status effect called “Bats” which triggered via onAttacked. All this did was reduce the incoming damage to a max of 1. After applying the damage, I would reset the sprite based on it’s health.</p>

    <p>The sprite updating loop here is driven entirely by a status effect because it’s based on the health of the bats. 1HP = 1 BAT.</p>

    <p><img src="/assets/resources/posts/deeper/FullBats.gif" alt="Gif of bats being attacked and disappearing one by one." class="centered" /></p>
  </li>
  <li>
    <h3 id="creating-the-androidboy">Creating the AndroidBoy</h3>

    <p>So figuring out the resolution with viewport height and width was great. I made everything in 144 x 160, but can set the scale and make sure it’s big enough to see. The other cool thing about this is that if you set your Control nodes up a certain way, an Android device in portrait isn’t capable of scaling to fit a square window. Here’s where a cool trick came into play.</p>

    <p>I created debug buttons that would just send input messages. That means if I had one of these debug buttons on screen and pressed it, it would work exactly like if someone were to hit w,a,s,d on the keyboard. So I arranged these debug keys to look like GameBoy button layout and because the Android in portrait would not scale the window large and out-of-proportion, placing said debug button layout directly below the game window means they showed up when you played on Android. And even better, on desktop since it can scale the window and stay square, they just get hidden and cutoff. They’re there just outside the bounds of the window, waiting to be pressed by some hacker. Here they are just below the fold in the Base Screen.</p>

    <p><img src="/assets/resources/posts/deeper/ControlsInEngine.png" alt="Screenshot of the Godot Engine project, a row of game screens extending left to right while gray buttons in the shape of a bottom half of a GameBoy sit below everything." class="centered" /></p>

    <p>Now, on desktop, because we force a certain resolution and aspect ratio, it looks like this:</p>

    <p><img src="/assets/resources/posts/deeper/DesktopControls.png" alt="Screenshot of the game window, no controls are present." class="centered" /></p>

    <p>But through the magic of locking resolutions and hiding junk off screen, here is how it appears when you click play on your phone:</p>

    <p><img src="/assets/resources/posts/deeper/MobileControls.jpg" alt="Screenshot of the game window, no controls are present." class="centered" style="height: 550px;" /></p>
  </li>
</ol>

<h2 id="what-could-be-better">What Could Be Better</h2>

<ol>
  <li>
    <h3 id="art">Art!</h3>
    <p>Listen, I’m not an artist. I’m a card-carrying, practicing programmer. The only reason any of this is even presentable is because I chose a format that has nothing but incredibly low res pixel art and there’s a breadth of reference material.</p>

    <p>I looked long and hard at Phantasy Star for the character, back-of-head art. I also made sure to stop at back of head and never show a front. Faces are hard.</p>
  </li>
  <li>
    <h3 id="needed-even-more-content">Needed even more content!</h3>
    <p>This game is an extraction RPG. Right now there are 22 pieces of equipment in the game, and some of those are actually marked as unique. That means that if you play for a little while, there are less than 20 pieces of equipment to get. Now, you can also find palettes in the dungeon and trophies, so that’s the entirety of the loot set, but I still think if the point of the game is to find equippable loot, there should be more of it.</p>
  </li>
  <li>
    <h3 id="the-classes-werent-fully-baked">The classes weren’t fully baked.</h3>
    <p>This kinda falls into the more content category. Creating moves was the most taxing piece of content to produce. Anything unique that it did would require code and testing. On top of that, if I didn’t already have something I could use for the VFX, I had to create animated sprites. I envisioned several classes with movelists of about 8 to 10. I got five classes with 4 - 6 moves each.</p>

    <p>I underestimated this one quite a bit and ended up pushing it off to focus on the three bosses in the game instead. I also did some silly stuff like making a bard who has VFX that look kinda like music notes of the actual SFX that are being played. (But again, programmer, so that might be way horrible too!)</p>
  </li>
</ol>

<h2 id="in-conclusion">In Conclusion</h2>

<p>Water sucks.</p>

<p><a href="https://binarysolo.itch.io/deeper">You can play the game on itch.</a></p>

<p>I’ve got something of a system going here with making stuff on my phone, and that doesn’t end here on Deeper!</p>]]></content><author><name></name></author><category term="blog" /><category term="postmortem" /><summary type="html"><![CDATA[Deeper is my second game for Tiny Mass Games as well as my second project in Godot and my second time using my phone to make a game. It is an action-esque, turn-based, extraction RPG. It is a GameBoy aesthetic party-based battle system with time bars instead of mana.]]></summary></entry><entry><title type="html">A Talk About Parenting</title><link href="http://chadpluspl.us/talk/lightning/2025/02/17/parenting-is-hard.html" rel="alternate" type="text/html" title="A Talk About Parenting" /><published>2025-02-17T14:22:03+00:00</published><updated>2025-02-17T14:22:03+00:00</updated><id>http://chadpluspl.us/talk/lightning/2025/02/17/parenting-is-hard</id><content type="html" xml:base="http://chadpluspl.us/talk/lightning/2025/02/17/parenting-is-hard.html"><![CDATA[<iframe width="1080" height="608" src="https://www.youtube.com/embed/5H0y9-x6eZ0?si=Kv5MkwUnesDWVqWb&amp;start=1066" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Parenting is really hard. No matter how many times someone tells you the things that are hard about parenting, this will not sink in and you will think you will be just fine. I will walk you through the entire life cycle of raising your children and I will constantly remind you how difficult it is.</p>

<p>Will you listen?</p>

<p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSRL03uGFXBxmFjlRWNft5HeO5SjZojhYxTZUa8_14K8Ifm_HiZZylX5Tphn5G_oocAPX-_IWvwWaF_/pubembed?start=false&amp;loop=false&amp;delayms=60000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe></p>]]></content><author><name></name></author><category term="talk" /><category term="lightning" /><summary type="html"><![CDATA[This is a talk about parenting. It is definitely not about anything else.]]></summary></entry><entry><title type="html">Postmortem: Standoff!</title><link href="http://chadpluspl.us/blog/postmortem/2024/07/24/standoff-postmortem.html" rel="alternate" type="text/html" title="Postmortem: Standoff!" /><published>2024-07-24T18:10:00+00:00</published><updated>2024-07-24T18:10:00+00:00</updated><id>http://chadpluspl.us/blog/postmortem/2024/07/24/standoff-postmortem</id><content type="html" xml:base="http://chadpluspl.us/blog/postmortem/2024/07/24/standoff-postmortem.html"><![CDATA[<p>Standoff! is my first foray into the world of <a href="http://www.tinymassgames">Tiny Mass Games</a>. It is a card game about deceit and limited information. Attack the players to your left or right while trying to co-ordinate with others to become the last person standing. Part of my concession, was that I was actually too busy to put a lot of time into this, so I was going to be doing this pretty much on my phone. (Wait, what? Yep! <a href="/talk/lightning/2023/10/24/i-made-a-game-on-my-phone.html">On my phone.</a>)</p>

<p><a href="https://binarysolo.itch.io/standoff">You can play the game on itch.</a></p>

<p>This was also my first adventure in using Godot, an open source engine that some people compare to Unity. It is similar in that there’s an object hierarchy and a Decorator, Composition-ish pattern. It’s also, available on the Google Play Store. So with two and a half months and a phone, Standoff! was born.</p>

<h2 id="what-did-i-do-on-my-phone">What Did I Do On My Phone</h2>
<p>Pretty much everything! I say pretty much because the only parts I didn’t do were things that just weren’t possible via phone.</p>

<ul>
  <li>I did all of the UI art via Pixel Studio Pro.</li>
  <li>Particles and lighting directly in-editor in Godot!
    <ul>
      <li>
        <p>(I actually like how this fire came out!)</p>

        <p><img src="/assets/resources/posts/standoff/FireParticles.gif" alt="Chunky spherical fire particles float up like little flames in a low-poly campfire." /></p>
      </li>
    </ul>
  </li>
  <li>I wrote all the code in GDScript. That includes:
    <ul>
      <li>A card-based, ability system.</li>
      <li>Game logic.</li>
      <li>Unique AIs per character.</li>
      <li>Menus and UI!</li>
      <li>Saving player data.</li>
      <li>Controlling character animations.</li>
    </ul>
  </li>
</ul>

<h2 id="what-i-did-on-a-computer">What I Did On a Computer</h2>
<p>Well, turns out the FMOD GDExtension didn’t work out because… Android doesn’t support extensions in 4.0. (Support was added in 4.2 but, due to a bug, the FMOD extension doesn’t load because the engine can’t load libraries that depend on other libraries from internal memory. This was fixed in 4.3!) Unfortunately, and fortunately, I had already gotten cool dynamic music from <a href="http://www.garrettrose.com">Garret Rose</a>, so I ended up doing all audio related work on a laptop. This was a little tedious because I had to develop new features and merge them into an audio branch that constantly had conflicts. If I had more time, I could have just done an interface to cover this up and make it mergeable.</p>

<p><em>Another issue:</em> You can’t import 3D models on Android! The gltf importer didn’t work as of 4.0, so all models and animations had to be imported on a laptop. The gltf importer is, I believe, an executable, so it can’t run on Android. I added them to the project on my laptop and committed it. After the initial import, however, you can set them up and mess with the models via mobile. It’s just the initial import that isn’t mobile friendly. You can animate, tweak materials, and everything else.</p>

<p><em>Lastly,</em> I generated all my builds on a computer. (Godot calls this Exporting.) The Android editor doesn’t have the capability to run the Export commands. That doesn’t sound unreasonable, as generating binaries requires quite a bit of platform-specific code. Save for mobile, it seems best to actually export from the desired platform.</p>

<p><img src="/assets/resources/posts/standoff/CinematicIntro.gif" alt="The characters do the whole Good, Bad, and the Ugly close-up eye shot thing." class="centered" /></p>

<h2 id="what-i-learned">What I Learned</h2>
<ol>
  <li>
    <h3 id="how-to-use-the-godot-editor">How to use the Godot editor!</h3>
    <p>Coming into this I had literally zero knowledge of Godot. To do this on my phone, I ended up having to use GDScript. GDScript is a lot like python. I had already messed around with python for our build system at BioWare, so it wasn’t too hard to pick up. I found the documentation to be pretty fantastic. Everything I did was pretty much the bare bones version, so I never ran into something that didn’t have a tutorial available. Whether it was the Godot docs themselves (which are also an open source, maintained product) or a Youtube video tutorial, the info I needed I could always find. The simplest takeaways: There are lots of Node types that do what you want and whitespace matters.</p>
  </li>
  <li>
    <h3 id="how-to-use-mixamo-for-animations">How to use Mixamo for animations.</h3>
    <p>I used basic Synty models to give characters an on-screen presence. To animate them, I dug into the world of Mixamo to animate humanoids. At Full Sail they taught us about animation and I did mess around with Maya. But that knowledge level is cursory at best. For Mixamo, they make it super easy to find animations, check them with your models, and download them for use in your project. Unfortunately, Godot isn’t great with fbx models. Everything had to be changed into a gltf or glb, the open source format. Luckily, I was able to figure out a pipeline to get models and animations implemented by doing a one-time import with certain args using FBXtoGLTF. I’ve been doing so much 2D lately, it was a much needed refresher.</p>
  </li>
</ol>

<h2 id="what-worked">What Worked</h2>
<ol>
  <li>
    <h3 id="prototype-early">Prototype early.</h3>
    <p>I did a really quick paper prototype at GDC using a deck of cards and immediately knew the basic idea could work. Having the deck of cards be the most basic form of gameplay gave me a huge leg up on design work. I had the numbers, the four types of cards, and an easy way to play with it and deal it out even when it was just me. Luckily, this concept translated quickly to digital as well. The base gameplay was done early and then all of the learning was figuring out how to make it work visually.</p>
  </li>
  <li>
    <h3 id="simple-idea">Simple Idea</h3>
    <p>The game didn’t require a plethora of features in order to get working. Deal cards. Play cards. Track health. That’s all you really need in this game. I could have let it creep in scope. I did slightly. But I could have went networked. (I actually spent a day seeing if it was easy enough and then decided not to do it.) I could have shown players an entire hand of cards instead of forcing them to do one at a time. I’m sure I could have made much crazier cards. But I spent some time doing polish instead.</p>
  </li>
</ol>

<h2 id="what-could-be-better">What Could Be Better</h2>
<ol>
  <li>
    <h3 id="legibility">Legibility!</h3>
    <p>I used UI to do a lot of the card and button work, but that bit me a little bit when I wanted to implement animations and effects to make the game clearer to understand. I ran out of time for multiple reasons, but in the end I just have cards flying to the left or right of the screen when it would have been much clearer to create a 3D instance that flies to the actual player.</p>

    <p><img src="/assets/resources/posts/standoff/DealCards.gif" alt="Player chooses whether cards are given to the player on the left or right." class="centered" /></p>

    <p>I was also stubborn and stuck on this over the shoulder view, so getting the camera angles good for all players took a lot of time. Time that would have been better used if I had just done a top down view to start and been willing to show the flow of the cards more easily that way. I’m happy with the cinematic quality it has, but it was slightly at the cost of clarity.</p>
  </li>
  <li>
    <h3 id="stick-to-a-theme">Stick To a Theme</h3>
    <p>This one was just a mismatch between what I had in my head and what I had on my computer. When I started developing the idea I was intent on a wacky mashup of wizards, knights, guns, and others. I drew all of the card art on my phone during the intermission of Disney on Ice. I avoided guns because I thought of swords and shields when I made the deck of cards prototype.</p>

    <p><img src="/assets/resources/posts/standoff/CowboysUsingSwords.gif" alt="Players use cards to attack each other, although animations are sync'd up to the UI, it's still cowboys using cards with goofy swords on them." class="centered" /></p>

    <p>The first pack I had on my machine was an old Synty Western pack. Then I got a fun idea to use the ‘The Good, The Bad, and the Ugly’ shots of the eyes to start each game to sell that distrust element. From there, I felt like I really went full on Serious Western with the vibe while UI has this sketchy fun feel to it. I should have either added more over-the-top models, injected some humor, or just re-did the cards to be a gunslingin’ theme instead.</p>
  </li>
  <li>
    <h3 id="the-code">The Code!</h3>
    <p>This one is less an issue in architecture and more of a learning curve. The game is kind of buggy in some respects, and that can mostly be attributed to learning a new language with different paradigms on an engine that’s just starting to mature. No problem admitting there were some hacks or even just lessons learned down the road that there wasn’t time to go back and fix.</p>
  </li>
</ol>

<h2 id="in-conclusion">In Conclusion</h2>
<p>It was an interesting experience making the game mostly via mobile. I think for a game developed in stolen moments it came out relatively well. Definitely leaned more game jam than small project, but such was the constraints of the time and tools.</p>

<p><a href="https://binarysolo.itch.io/standoff">Again, you can play the game on itch.</a></p>

<p>Unless you follow the <a href="https://binarysolo.itch.io/">Binary Solo itch page</a> or subscribe to the <a href="http://subscribepage.io/uwNffE">Tiny Mass Games newsletter</a>, you might be wondering if I would do it again. Well, I released another game called Deeper which I started on my computer and ended up putting a lot more work into via mobile when my house was flooded. So yes, I did do it again and I shall continue to do it. I’m sure it’s unhealthy to think of this idle time as wasted, but it feels damn good when you are able to create and test a feature on your phone. Grab Godot on the Play Store and give it a try.</p>]]></content><author><name></name></author><category term="blog" /><category term="postmortem" /><summary type="html"><![CDATA[Standoff! is my first foray into the world of Tiny Mass Games. It is a card game about deceit and limited information. Attack the players to your left or right while trying to co-ordinate with others to become the last person standing. Part of my concession, was that I was actually too busy to put a lot of time into this, so I was going to be doing this pretty much on my phone. (Wait, what? Yep! On my phone.)]]></summary></entry><entry><title type="html">Perfect is the Enemy of Fun!</title><link href="http://chadpluspl.us/talk/lightning/2024/06/18/perfect-algorithms.html" rel="alternate" type="text/html" title="Perfect is the Enemy of Fun!" /><published>2024-06-18T14:22:03+00:00</published><updated>2024-06-18T14:22:03+00:00</updated><id>http://chadpluspl.us/talk/lightning/2024/06/18/perfect-algorithms</id><content type="html" xml:base="http://chadpluspl.us/talk/lightning/2024/06/18/perfect-algorithms.html"><![CDATA[<iframe width="1080" height="608" src="https://www.youtube.com/embed/FY2wg9NPYjM?si=Vwf--SEtfcE2yTR2&amp;start=2319" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>As with most lightning talks I do, I thought of something dumb in the shower and built ten minutes around it. This time, it was a sight gag about the speed of pixels. I had a slightly different version of this talk prepared, but decided to move it towards how thinking of programming in terms of simulating reality can sometimes be a waste of time.</p>

<p>(I might have embellished the BioWare stuff from something I heard third hand from a designer. That’s called story-telling!)</p>

<p>This talk was presented at Boston Indies Lightning Talks. Presentations are limited to 10 minutes a piece and can cover a variety of topics.</p>

<p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQvjcCT1rwuldGQDo7oSqKtUAg9NsL4K9F1znzX4rq253ieEBQCV2UgmkVbAqyxUYdl2z3oGBri5Lam/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe></p>]]></content><author><name></name></author><category term="talk" /><category term="lightning" /><summary type="html"><![CDATA[A talk about how super real algorithms sometimes suck.]]></summary></entry><entry><title type="html">I Made a Game on My Phone!</title><link href="http://chadpluspl.us/talk/lightning/2023/10/24/i-made-a-game-on-my-phone.html" rel="alternate" type="text/html" title="I Made a Game on My Phone!" /><published>2023-10-24T14:22:03+00:00</published><updated>2023-10-24T14:22:03+00:00</updated><id>http://chadpluspl.us/talk/lightning/2023/10/24/i-made-a-game-on-my-phone</id><content type="html" xml:base="http://chadpluspl.us/talk/lightning/2023/10/24/i-made-a-game-on-my-phone.html"><![CDATA[<iframe width="1080" height="608" src="https://www.youtube.com/embed/tEU43E3Mkhs?si=_6adrv0EwHTWWNU5&amp;start=1840" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Over the past year I have been participating in a cool little initiative / co-op / experiment called <a href="http://www.tinymassgames.com">Tiny Mass Games</a>. Every 2 - 3 months we try to develop and launch new games. The stars aligned for the second season of the program and I decided to do something insane: Do it entirely on my phone. I mostly succeeded and this is how.</p>

<p>This talk was presented at Boston Indies Lightning Talks. Presentations are limited to 10 minutes a piece and can cover a variety of topics.</p>

<p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQORhGpaNfYMluqcBD5MS6Q9iT8Y5ZMDJBit9Z5yLxQ-uV4_Odkp5igAHK0zSpSLhp7oCJWnECrrZh6/embed?start=false&amp;loop=false&amp;delayms=60000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe></p>]]></content><author><name></name></author><category term="talk" /><category term="lightning" /><summary type="html"><![CDATA[Over the past year I have been participating in a cool little initiative called Tiny Mass Games. Every 2 - 3 months we try to develop and launch new games. The stars aligned for the second season and I tried something insane. Make a game on my phone.]]></summary></entry><entry><title type="html">I Make Games on My Phone!</title><link href="http://chadpluspl.us/talk/short/2023/10/24/i-make-games-on-my-phone.html" rel="alternate" type="text/html" title="I Make Games on My Phone!" /><published>2023-10-24T14:22:03+00:00</published><updated>2023-10-24T14:22:03+00:00</updated><id>http://chadpluspl.us/talk/short/2023/10/24/i-make-games-on-my-phone</id><content type="html" xml:base="http://chadpluspl.us/talk/short/2023/10/24/i-make-games-on-my-phone.html"><![CDATA[<iframe width="1080" height="608" src="https://www.youtube.com/embed/qoCWp_oP9Ng?si=ffagFG9vFCZBfYpu" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>I gave a talk at Boston Indies Lightning Talks all about how I made a game on my phone. It was a crazy experiment for <a href="http://www.tinymassgames.com">Tiny Mass Games</a>. Little did I know, folks would actually want to know more.</p>

<p>For GodotCon, after a couple more phones made on my Android phone, I decided to give an updated, unabridged talk with lessons learned since that first game.</p>

<p><iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQjGmJ09fFLMMmCoNgSU-b97R3hqQ57Jvj101AoeiM6VL-G-3W2Rz1u-S7lU6u5xX-_vHhMtGnwup5t/pubembed?start=false&amp;loop=false&amp;delayms=60000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe></p>]]></content><author><name></name></author><category term="talk" /><category term="short" /><summary type="html"><![CDATA[I tried something insane. Make a game on my phone. Then I kept doing it.]]></summary></entry><entry><title type="html">Actually Useful Unreal Documentation</title><link href="http://chadpluspl.us/blog/tip/2022/11/22/actually-useful-unreal-documentation.html" rel="alternate" type="text/html" title="Actually Useful Unreal Documentation" /><published>2022-11-22T19:33:03+00:00</published><updated>2022-11-22T19:33:03+00:00</updated><id>http://chadpluspl.us/blog/tip/2022/11/22/actually-useful-unreal-documentation</id><content type="html" xml:base="http://chadpluspl.us/blog/tip/2022/11/22/actually-useful-unreal-documentation.html"><![CDATA[<p>Okay, no way to dance around this one. The official documentation for Unreal Engine isn’t all that useful. If it’s not just auto-generated from heaps of engine code, there is some really wrong. Rarely, if ever does the Unreal Documentation provide much help besides telling you which file to include in order to make a type compile. (And honestly, if you’re not getting that for free from Rider or Visual Studio, you need to upgrade.) If you have a question about the return type? Go dig through the function in the engine code. Wondering if you can safely put nullptr as an argument? Give it the old college try and see if it crashes.</p>

<p>All is not lost, however! There are a many great scholars out there compiling their knowledge onto their own sites to help us Information Peasants. Here are some useful sites for Unreal Engine beginners such as myself.</p>

<h3 id="ben-ui">Ben UI</h3>

<p><a href="https://benui.ca/unreal">https://benui.ca/unreal</a></p>

<p>Ben has tons of helpful tutorials, videos, and reference materials. While he advertises as a UI guy, and there definitely are a more UI focuses tutorials on the site, Ben also has a lot of general purpose knowledge to impart. One of the strengths of this site is that there are a lot of articles which cover the plethora of ways to do something, noting the tradeoffs. (Or sometimes the reason why to never do it that way.)</p>

<p>There are many different types of pages from tutorials, discussions, and documentation. Here is an example of a great Documentation Page that I reference constantly: <a href="https://benui.ca/unreal/uproperty/">https://benui.ca/unreal/uproperty/</a></p>

<h3 id="jipdev">JIP.dev</h3>

<p><a href="https://jip.dev/notes/unreal-engine/">https://jip.dev/notes/unreal-engine/</a></p>

<p>JIP, JORGE ISRAEL PEÑA, is a software engineer with a knowledge on a great many things. It seems part of his learning method is to extensively document. One of the many topics that he has transcribed his learnings is Unreal Engine. His “Notes” cover a wealth of topics from top-to-bottom, and could be used as beginner reading. Starts with project structure, naming conventions, and terminology and then moves through increasingly advanced topics such as Garbage Collection, Building, and more.</p>

<h3 id="unreal-slackers">Unreal Slackers</h3>

<p><a href="https://unrealslackers.org/">https://unrealslackers.org/</a></p>

<p>A little disappointing that this is a Discord server and not a Slack. You know, just naming wise. However, this is a good community that has a lot of members. It can be kind of hard to follow in some channels, but it has a lot of knowledge. Sometimes it can be hit or miss with questions, but it’s a good place to try regardless.</p>

<h3 id="the-unreal-developer-network">The Unreal Developer Network</h3>

<p><a href="https://udn.unrealengine.com/">https://udn.unrealengine.com/</a></p>

<p>Okay, so this one is basically the official GOOD forums for Unreal. <strong>It isn’t free.</strong> But for every Unreal forum post you find on Google with the same few suggestions that aren’t relevant, the UDN has a depth of serious developers with in-depth answers.</p>]]></content><author><name></name></author><category term="blog" /><category term="tip" /><summary type="html"><![CDATA[Okay, no way to dance around this one. The official documentation for Unreal Engine isn’t all that useful. If it’s not just auto-generated from heaps of engine code, there is some really wrong. Rarely, if ever does the Unreal Documentation provide much help besides telling you which file to include in order to make a type compile. (And honestly, if you’re not getting that for free from Rider or Visual Studio, you need to upgrade.) If you have a question about the return type? Go dig through the function in the engine code. Wondering if you can safely put nullptr as an argument? Give it the old college try and see if it crashes.]]></summary></entry></feed>