<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Jesdo Software</title>
        <link>https://www.jesdosoftware.com</link>
        <description>Jesdo Software announcements, news, and blog posts</description>
        <image>
            <link>https://www.jesdosoftware.com</link>
            <title>Jesdo Software</title>
            <url>https://www.jesdosoftware.com/assets/optimized/jesdo-logo-144x144.png</url>
            <height>144</height>
            <width>144</width>
        </image>
        <copyright>Copyright 2025 Jesdo Software LLC. All rights reserved.</copyright>
        <language>en-us</language>
        <lastBuildDate>Fri, 04 Apr 2025 02:47:24 GMT</lastBuildDate>
        <managingEditor>jesse@jesdosoftware.com (Jesse Douglas)</managingEditor>
        <webMaster>jesse@jesdosoftware.com (Jesse Douglas)</webMaster>
        <atom:link href="https://www.jesdosoftware.com/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title>Unity: strongly typed game object fields — how and why</title>
            <link>https://www.jesdosoftware.com/posts/2018-10-30-unity-strongly-typed-game-object-fields</link>
            <guid>https://www.jesdosoftware.com/posts/2018-10-30-unity-strongly-typed-game-object-fields</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/enemycontroller_weaponcontrollerfield.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Often in Unity one game object in a scene must reference another. Unity lets us do this by adding a public field to a
script, which we can then set within Unity's inspector to another object. For example, let's say we have an enemy
object that needs a reference to a weapon object.&lt;/p&gt;
&lt;p&gt;Our hypothetical enemy object has a script named EnemyController, with a public field named Weapon. Our weapon object
is a game object, so it makes sense to declare Weapon as type GameObject:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/enemycontroller_gameobjectfield.png" alt="EnemyController's Weapon field with type GameObject" /&gt;&lt;/p&gt;
&lt;p&gt;This lets us drag our weapon object into the Weapon field and be on our way:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/enemyinspector_gameobjectfield.jpg" alt="A weapon object assigned to an Enemy's Weapon field" /&gt;&lt;/p&gt;
&lt;p&gt;But there's a bug here waiting for an opportunity to strike. What if we drag in a different object, that's not a
weapon? Either by accident, or because it's six months after we added the Weapon field and don't remember what it
requires. As things stand in our example, Unity doesn't mind:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/enemyinspector_notaweapon.jpg" alt="A non-weapon object assigned to an Enemy's Weapon field" /&gt;&lt;/p&gt;
&lt;p&gt;Everything will build and run fine, until your enemy tries to invoke UseWeapon on the Weapon field's WeaponController
component. The NotAWeapon object doesn't have a WeaponController component, so it'll throw an exception.&lt;/p&gt;
&lt;p&gt;I always prefer to catch errors at build time (or even better, design time) rather than run time whenever possible.
Run time testing is tedious and error-prone, and later modifications can cause regression errors that require
additional (endless?) testing to catch. It'd be great if Unity could catch errors like this for us as soon as we
make them, so we know as fast as possible that something is wrong.&lt;/p&gt;
&lt;p&gt;Thankfully, Unity will catch these types of error at design time, if we use strongly typed fields. That is, instead
of making a field type GameObject, which could be anything, make the field the same type as a component we need the
object to have.&lt;/p&gt;
&lt;p&gt;In our example we expect the weapon object to have a WeaponController component. Therefore we can make our Weapon
field type WeaponController:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/enemycontroller_weaponcontrollerfield.png" alt="EnemyController's Weapon field as type WeaponController" /&gt;&lt;/p&gt;
&lt;p&gt;This will prevent us from setting the Weapon field to any object that doesn't have a WeaponController component:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/posts/2018-10-30-unity-strongly-typed-game-object-fields/trysetnotaweapon.gif" alt="Unity not allowing assignment of a non-weapon object to the Weapon field typed as WeaponController" /&gt;&lt;/p&gt;
&lt;p&gt;It also has the bonus of simplifying our EnemyController code. Instead of getting the WeaponController component from
the Weapon object to call UseWeapon, we can call UseWeapon directly on the Weapon object. This is because Weapon
here is a direct reference to the WeaponController component, rather than to the game object itself. (If you need to
access its game object, you can do so via Weapon.gameObject.)&lt;/p&gt;
&lt;p&gt;Strongly typed field references also work polymorphically. That is, if the field type is a base class, you can assign
any subclass to it. For example, let's say WeaponController is an abstract base class:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/abstractweaponcontroller.png" alt="WeaponController as an abstract class" /&gt;&lt;/p&gt;
&lt;p&gt;And SwordController is a concrete subclass of WeaponController:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2018-10-30-unity-strongly-typed-game-object-fields/weaponcontrollersubclass.png" alt="A concrete subclass of WeaponController named SwordController" /&gt;&lt;/p&gt;
&lt;p&gt;Unity won't let us add a WeaponController component to a game object, because it's an abstract class. So to create a
sword game object, we need to add the concrete SwordController component to it. But we want our enemy to be capable
of using any type of weapon, not just swords, so we leave EnemyController.Weapon as type WeaponController. Since
SwordController extends WeaponController, we can still make the assignment:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/posts/2018-10-30-unity-strongly-typed-game-object-fields/setsword.gif" alt="Setting a SwordController object in a WeaponController field" /&gt;&lt;/p&gt;
&lt;p&gt;This gives us flexibility (the ability to use weapons interchangeably) and loose coupling (not designing weapons to
be used by specific types of enemy, and vice versa) without sacrificing type safety.&lt;/p&gt;
&lt;p&gt;Of course, there will be cases where typing a field like this won't work. You may expect a given game object to have
multiple components. Or no necessary components. But a lot of the time, using strongly typed fields is appropriate,
and will grant peace of mind and less time spent fixing this class of bug.&lt;/p&gt;
</description>
            <pubDate>Tue, 30 Oct 2018 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Privacy policy and EULA updates (Oct. 2021)</title>
            <link>https://www.jesdosoftware.com/posts/2021-10-27-privacy-policy-eula-updates-2021-10</link>
            <guid>https://www.jesdosoftware.com/posts/2021-10-27-privacy-policy-eula-updates-2021-10</guid>
            <description>&lt;p&gt;We've made the following changes to our &lt;a href="https://www.jesdosoftware.com/privacy-policy"&gt;Privacy Policy&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reflect moving site hosting from WordPress.com to Microsoft Azure&lt;/li&gt;
&lt;li&gt;Reflect removing all first- and third-party cookies&lt;/li&gt;
&lt;li&gt;Clarify which third-party services we use and what data they collect&lt;/li&gt;
&lt;li&gt;Add links to third-party privacy policies&lt;/li&gt;
&lt;li&gt;Update language around the GDPR Standard Contractual Clauses&lt;/li&gt;
&lt;li&gt;Correct the email address to send us electronic mail&lt;/li&gt;
&lt;li&gt;Update the address to send us physical mail&lt;/li&gt;
&lt;li&gt;Make minor formatting revisions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We've also made the following changes to the &lt;a href="https://www.jesdosoftware.com/dtmb/eula"&gt;License Agreement&lt;/a&gt; for &lt;a href="https://www.jesdosoftware.com/dtmb"&gt;Don't Take My Beans!&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow reproductions and derivative works for commercial purposes as well as non-commercial, as long as they remain within compliance of the License Agreement&lt;/li&gt;
&lt;li&gt;Update the address to send us physical mail&lt;/li&gt;
&lt;li&gt;Make minor formatting revisions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please contact us at &lt;a href="mailto:jesse@jesdosoftware.com"&gt;jesse@jesdosoftware.com&lt;/a&gt; with any questions.&lt;/p&gt;
</description>
            <pubDate>Wed, 27 Oct 2021 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>We have a new website!</title>
            <link>https://www.jesdosoftware.com/posts/2021-10-27-new-website</link>
            <guid>https://www.jesdosoftware.com/posts/2021-10-27-new-website</guid>
            <description>&lt;p&gt;Jesdo Software has a new website! Ahead of the launch of our upcoming game &lt;a href="https://www.jesdosoftware.com/dtmb"&gt;Don't Take My Beans!&lt;/a&gt;, we've taken a bit of time to upgrade from a blog on WordPress.com to a full-fledged, custom-built site.&lt;/p&gt;
&lt;p&gt;Creating a new website from scratch is a lot of work, but it provides these benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full control over the design and content of the site, without having to either pay for an expensive WordPress.com plan or self-host a WordPress instance, and without having to revisit my old PHP developer days and create a custom WordPress theme&lt;/li&gt;
&lt;li&gt;An easy way to share updates without relying on back-end servers or databases&lt;/li&gt;
&lt;li&gt;A site that operates without cookies or other forms of tracking, and is fully functional without JavaScript yet provides a smoother experience for those with JavaScript enabled&lt;/li&gt;
&lt;li&gt;The ability to share the site's codebase as an open source project (more on that to come soon)&lt;/li&gt;
&lt;li&gt;A way for me to keep up-to-date with non-game-dev, web development skills ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have some exciting things in the works, not least of which is the full, official release of &lt;a href="https://www.jesdosoftware.com/dtmb"&gt;Don't Take My Beans!&lt;/a&gt;, so watch this space for updates. You can sign up for our mailing list or follow us on social media below to stay up-to-date on what we're doing.&lt;/p&gt;
&lt;p&gt;I also plan to author a technical write-up on the new site's implementation, and make the repo on GitHub public so others can see the code, so stay tuned for that.&lt;/p&gt;
&lt;p&gt;One final note: we've updated our &lt;a href="https://www.jesdosoftware.com/privacy-policy"&gt;privacy policy&lt;/a&gt; to reflect the changes to the site's implementation and hosting, as detailed &lt;a href="https://www.jesdosoftware.com/posts/2021-10-27-privacy-policy-eula-updates-2021-10"&gt;in this post&lt;/a&gt;.&lt;/p&gt;
</description>
            <pubDate>Wed, 27 Oct 2021 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Happy Halloween! ARanormal, our first game, is now open source!</title>
            <link>https://www.jesdosoftware.com/posts/2021-10-29-aranormal-is-now-open-source</link>
            <guid>https://www.jesdosoftware.com/posts/2021-10-29-aranormal-is-now-open-source</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2021-10-29-aranormal-is-now-open-source/aranormal-icon.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Happy Halloween!&lt;/p&gt;
&lt;p&gt;Five years ago we released our first game: ARanormal, an augmented reality (AR) ghost hunting simulation for iPhone. It's no longer available on the App Store, but in the &lt;em&gt;spirit&lt;/em&gt; of Halloween, and to demonstrate the commitment we want to make toward open source and software preservation, we've released ARanormal's source code to the public.&lt;/p&gt;
&lt;p&gt;ARanormal simulates a haunting in your own home. Turn off the lights and launch the app, and use your phone's camera to record paranormal activity around you. When you spot a ghost, take a picture to increase your score. Your phone may also pick up signals of otherwordly communication; ask questions aloud to prompt a response! But be careful not to provoke them…&lt;/p&gt;
&lt;p&gt;We've put the source code on GitHub here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/JesdoSoftware/ARanormal"&gt;https://github.com/JesdoSoftware/ARanormal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ARanormal uses some third-party frameworks and assets we don't have permission to distribute with the source code; these are described in the README. It also requires an older version of Xcode to build, and I'm not sure how it'll run on modern iPhones. We consider it a legacy project and don't intend to maintain it, release any new versions, or offer support. But we're interested to hear if anyone gets it working!&lt;/p&gt;
&lt;p&gt;Have a safe and fun Halloween!&lt;/p&gt;
</description>
            <pubDate>Fri, 29 Oct 2021 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>New Don't Take My Beans! early access release!</title>
            <link>https://www.jesdosoftware.com/posts/2021-12-29-dtmb-1-0-x-early-access</link>
            <guid>https://www.jesdosoftware.com/posts/2021-12-29-dtmb-1-0-x-early-access</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2021-12-29-dtmb-1-0-x-early-access/dtmb-icon.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Hope you're having a wonderful holiday season!&lt;/p&gt;
&lt;p&gt;We've released a new early access version of Don't Take My Beans! for iPhone and Android!&lt;/p&gt;
&lt;p&gt;This version includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Updates to the user interface to add clarity and support devices with display cutouts (e.g., camera notches)&lt;/li&gt;
&lt;li&gt;Gameplay adjustments, including a delay to advancing after an enemy encounter until clear of all projectiles, and an increase to the invulnerability duration after continuing&lt;/li&gt;
&lt;li&gt;Forge item cost adjustments&lt;/li&gt;
&lt;li&gt;Bug fixes and performance improvements&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let us know what you think! Install via &lt;a href="https://testflight.apple.com/join/dITAVVVa"&gt;TestFlight on iPhone&lt;/a&gt; or &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans&amp;amp;pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"&gt;Google Play on Android&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the full release, we're working on a few features to make things more engaging over time, including an online leaderboard, so you can compete with others for a high score! The full release is planned for early 2022.&lt;/p&gt;
&lt;p&gt;Wishing you a safe, healthy, and happy New Year!&lt;/p&gt;
</description>
            <pubDate>Wed, 29 Dec 2021 05:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Don't Take My Beans! has released on Android!</title>
            <link>https://www.jesdosoftware.com/posts/2022-09-04-dtmb-has-released-on-android</link>
            <guid>https://www.jesdosoftware.com/posts/2022-09-04-dtmb-has-released-on-android</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2022-09-04-dtmb-has-released-on-android/google-play-badge.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Just a quick, belated note to announce a major milestone: Don't Take My Beans! has officially launched on Android! You can download it on &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans"&gt;Google Play&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We hoped to have the iOS release out by now as well, which code-wise is ready but requires some updated assets for the App Store. There may be some delay with that, however; my son was born a couple weeks ago, several weeks earlier than expected. Naturally that's taking most of my time and focus these days! So we appreciate your patience, and as a reminder, DTMB is &lt;a href="https://testflight.apple.com/join/dITAVVVa"&gt;currently available on iOS via TestFlight&lt;/a&gt;.&lt;/p&gt;
</description>
            <pubDate>Sun, 04 Sep 2022 21:34:00 GMT</pubDate>
        </item>
        <item>
            <title>Don't Take My Beans! for iPhone has been postponed indefinitely</title>
            <link>https://www.jesdosoftware.com/posts/2022-12-10-iphone-release-postponed-indefinitely</link>
            <guid>https://www.jesdosoftware.com/posts/2022-12-10-iphone-release-postponed-indefinitely</guid>
            <description>&lt;p&gt;We're sad to announce we've postponed the iPhone release of Don't Take My Beans! indefinitely. Reasons include: lack of bandwidth on our part, DTMB's performance so far on Android, and having to create all new App Store assets (screen shots, trailer, etc.) to keep up with Apple's ever changing requirements. Unfortunately, at this time, finalizing the iPhone release doesn't seem to justify the additional cost and effort.&lt;/p&gt;
&lt;p&gt;On behalf of everyone who's worked on Don't Take My Beans!, I want to extend our most heartfelt thanks for your support, encouragement, and testing during this development process! Game development is not easy, but we had fun making this game, and we hope our hard work has brought you a little joy and excitement.&lt;/p&gt;
&lt;p&gt;And as a reminder, Don't Take My Beans! is out on Android! You can download it on &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans"&gt;Google Play&lt;/a&gt;.&lt;/p&gt;
</description>
            <pubDate>Sat, 10 Dec 2022 18:41:00 GMT</pubDate>
        </item>
        <item>
            <title>Don't Take My Beans! post-release retrospective, part 1: development and testing</title>
            <link>https://www.jesdosoftware.com/posts/2023-02-08-dtmb-retrospective-pt-1</link>
            <guid>https://www.jesdosoftware.com/posts/2023-02-08-dtmb-retrospective-pt-1</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2023-02-08-dtmb-retrospective-pt-1/dtmb-logo.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 1 of a retrospective/postmortem for our game &lt;a href="https://www.jesdosoftware.com/dtmb"&gt;Don't Take My Beans!&lt;/a&gt;, which we fully released on Android on July 26, 2022. You can download it for free from &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans"&gt;Google Play&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In the fall of 2017 my friend &lt;a href="https://tandreades.com/"&gt;Thad Andreades&lt;/a&gt; and I decided to make a video game together. This would be the first proper game development project for both of us. A year prior I had released &lt;a href="https://github.com/JesdoSoftware/ARanormal"&gt;ARanormal&lt;/a&gt;, an augmented reality ghost hunting simulation for iPhone developed in Swift, though that was more of a tech demo/proof of concept than a full-fledged game. But I was a professional software developer, and he produced 3D animation for virtual reality, so we felt we had the necessary skills.&lt;/p&gt;
&lt;p&gt;We decided to make our game for Android and iPhone, figuring it would maximize the game's reach since everyone has a smartphone. (Probably the biggest mistake we made, right out of the gate; more about that later.) I was also enamored with the challenge of creating a game that takes advantage of the mobile form factor despite its constraints. We planned to release it as free-to-play, though without a firm monetization model in mind (another big mistake). I had been thinking about making a simple action game based around quick time events, so we agreed to attempt something like that, set in a Mad Max–esque postapocalyptic future, designed to make the player feel like a badass. We codenamed the game QT Action.&lt;/p&gt;
&lt;p&gt;Since I primarily worked with C#/.NET and had experimented with &lt;a href="https://unity.com/"&gt;Unity&lt;/a&gt; some already, we used Unity for the game engine. I handled the coding and engine work, Thad handled the graphics and UI, and we shared design work. Later we recruited Thad's friend &lt;a href="https://soundwrench.com/"&gt;Gavin Slyman&lt;/a&gt; to do the sound design. After growing attached to the placeholder music we found in a collection of free tracks for YouTube videos, we reached out to the creator of that track, &lt;a href="https://www.ethanmeixsell.com/"&gt;Ethan Meixsell&lt;/a&gt;, and licensed a few tracks from him. We commissioned &lt;a href="https://claytonbelcher.com/"&gt;Clayton Belcher&lt;/a&gt; to create the app icon.&lt;/p&gt;
&lt;p&gt;As development progressed, we gave it the official name Don't Take My Beans! (DTMB), reflecting the player's quest to reclaim their hoard of canned food stolen by a gang of mutants and robots. The initial quick time event design shifted to that of a lane-based autorunner, though the player stopped running to exchange fire with each wave of enemies.&lt;/p&gt;
&amp;lt;figure&amp;gt;
    &amp;lt;img src=&amp;quot;/assets/posts/2023-02-08-dtmb-retrospective-pt-1/dtmb-enemy-cylinders.gif&amp;quot; alt=&amp;quot;DTMB's protagonist exchanging fire with crude cylinder placeholders for enemies&amp;quot; /&amp;gt;
    &amp;lt;figcaption&amp;gt;An early prototype of the player changing lanes and exchanging fire with enemies.&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;p&gt;Because this was a project pursued in our spare time, and because we had so much to learn along the way, DTMB's development lasted an unfortunate length of time. Having started in late 2017, we entered closed beta testing in March 2020, early access/open beta testing in March 2021, and launched the &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans"&gt;full production release&lt;/a&gt; on July 26, 2022. The full release only included Android, not iPhone; more on that later.&lt;/p&gt;
&lt;p&gt;DTMB was not a commercial or critical success, but thankfully it didn't have to be, as it was a side project with no real financial stakes. And we learned a lot, some of which I'll share here.&lt;/p&gt;
&amp;lt;figure&amp;gt;
    &amp;lt;img src=&amp;quot;/assets/posts/2023-02-08-dtmb-retrospective-pt-1/dtmb-finished.gif&amp;quot; alt=&amp;quot;Finished gameplay footage of DTMB&amp;quot; /&amp;gt;
    &amp;lt;figcaption&amp;gt;The finished product.&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;h2&gt;Unity's great…&lt;/h2&gt;
&lt;p&gt;As I mentioned, I'm a .NET developer by trade, so Unity with its C# scripting was a natural fit for me. Knowing the language already made it easy to jump in and get started, especially since I was mostly developing in the evening after work, and learning a new language on top of everything else would have been too much. I was also already familiar with the relevant tools. (I used &lt;a href="https://code.visualstudio.com/"&gt;Visual Studio Code&lt;/a&gt; for editing script files, since &lt;a href="https://visualstudio.microsoft.com/"&gt;Visual Studio&lt;/a&gt; proper felt too heavy, and so I could have the same development environment on Windows or a Mac.)&lt;/p&gt;
&lt;p&gt;Unity was nice for its visual scene editing and quickly seeing and testing changes. Thad and Gavin were able to jump in and make changes directly in the Unity project without much trouble, making integration with their assets simpler. Unity is a mature engine with lots of features, as well as lots of documentation and tutorials, so nothing we needed to do hadn't already been accounted for. Building for Android and iOS was as straightforward as Google and Apple allowed it to be. And though I &lt;a href="https://jessedouglas.net/posts/dot-net-dev-learns-unity-1/"&gt;initially bristled at Unity's game objects being essentially bags of components with no definite &lt;code&gt;is-a&lt;/code&gt; identity&lt;/a&gt;, I came to appreciate how it favors composition, and actually sort of miss that now that I'm experimenting with &lt;a href="https://godotengine.org/"&gt;Godot&lt;/a&gt;, which emphasizes inheritance.&lt;/p&gt;
&lt;h2&gt;…except Unity also kinda sucks&lt;/h2&gt;
&lt;p&gt;I mention experimenting with Godot, because by the end of developing DTMB, I had grown tired of Unity.&lt;/p&gt;
&lt;p&gt;As much as I love C#, I don't consider it a good language for game development. Relying on a garbage collector and lacking manual memory management means doing weird things like using structs when you'd normally use classes, and otherwise avoiding memory allocations on the heap, to prevent random pauses when the garbage collector kicks in. There were plenty of times I wished I could just delete objects. (Though to be fair, I could have done better at using techniques like object pooling to get more mileage out of my allocations.)&lt;/p&gt;
&lt;p&gt;One of the downsides of such a long-running project is keeping your tech stack up-to-date, but updating Unity wasn't always a smooth process. There was a point release that broke the game until several point releases later. There were API updates with changes requiring several fixes just to maintain the same behavior. But the worst offender: moving from Unity 2018 to 2019 broke some of our shaders. At that point Thad had mostly moved on to other things, and I didn't have the tools, knowhow, or time to fix them. So we remained on Unity 2018 for the rest of development.&lt;/p&gt;
&lt;p&gt;Unfortunately Unity 2018 locks us out of releasing updates on Android, because apps now need to &lt;a href="https://support.google.com/googleplay/android-developer/answer/11926878"&gt;target Android API level 31 or higher&lt;/a&gt;, for which &lt;a href="https://issuetracker.unity3d.com/issues/install-parse-failed-manifest-malformed-errors-are-thrown-when-trying-to-run-an-android-application-with-target-api-level-31"&gt;Unity had an issue building that wasn't fixed in 2018&lt;/a&gt;. Also, &lt;a href="https://developer.android.com/google/play/billing/deprecation-faq"&gt;apps with in-app purchases must now use Google Play Billing Library version 4&lt;/a&gt;, but &lt;a href="https://forum.unity.com/threads/how-to-use-unity-iap-4-4-with-unity-2019.1333335/"&gt;only Unity 2020 and higher support that&lt;/a&gt;. So we'd have to upgrade by at least two major Unity versions, and fix all the resultant issues, to push even a minor fix for DTMB, which is a level of effort I can't justify anymore. Eventually, if the target API level isn't increased, Google will stop making DTMB discoverable on Google Play. It's such a shame that a finished project has such a short lifespan imposed on it by platforms without constant, costly updates.&lt;/p&gt;
&lt;p&gt;Even beyond that, despite the investment I've made in learning Unity, it's become hard to trust them for future projects. They have a &lt;a href="https://www.reddit.com/r/gamedev/comments/rzef4u/is_unity_as_big_of_a_mess_as_people_say_it_is/"&gt;reputation for deprecating features and replacing them with new ones that never leave the experimental/beta phase&lt;/a&gt;. They've made a number of &lt;a href="https://www.gamedeveloper.com/culture/unity-we-weren-t-talking-enough-to-game-developers"&gt;decisions and acquisitions&lt;/a&gt; that have little to do with helping developers create games, suggesting a lack of focus on their core userbase. Their CEO &lt;a href="https://www.pocketgamer.biz/interview/79190/unity-ironsource-john-riccitiello-marc-whitten-merger/"&gt;makes crass comments about developers who value monetization less than their creative process&lt;/a&gt;. Nothing unexpected from a corporation that wants to drive growth and create shareholder value, but there's nothing stopping them from making decisions at the expense of small creators like me, and they've already shown a willingness to. Why put all my eggs in their basket?&lt;/p&gt;
&lt;h2&gt;Source control, project management, and integrating assets&lt;/h2&gt;
&amp;lt;figure&amp;gt;
    &amp;lt;img src=&amp;quot;/assets/optimized/posts/2023-02-08-dtmb-retrospective-pt-1/git.jpg&amp;quot; alt=&amp;quot;Hand-drawn diagram of Git commits and branches&amp;quot; /&amp;gt;
    &amp;lt;figcaption&amp;gt;My hand-drawn attempt at explaining Git.&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;p&gt;For source control, we used &lt;a href="https://git-scm.com/"&gt;Git&lt;/a&gt;, hosted in a private &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt; repository. There was a bit of a learning curve around Git for Thad and Gavin, since they weren't developers, but nothing insurmountable. I've heard others say Git doesn't work well with Unity, but we had no real issues, probably because we each had our own areas and didn't run into merge conflicts. None of our asset files was too huge, but we did use &lt;a href="https://git-lfs.com/"&gt;Git Large File System (LFS)&lt;/a&gt; for the larger files.&lt;/p&gt;
&lt;p&gt;We used GitHub issues to track tasks, which worked pretty well and let us keep everything in one place. Prior to the early access release, I tracked and prioritized issues using GitHub's &lt;a href="https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects"&gt;projects&lt;/a&gt;, which I find work well for a &lt;a href="https://en.wikipedia.org/wiki/Kanban_(development)"&gt;kanban&lt;/a&gt; style of development. But after that initial release, when we had to plan out future releases, I switched to using &lt;a href="https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/about-milestones"&gt;milestones&lt;/a&gt;, which I think work better for sprints that end with deliverables.&lt;/p&gt;
&lt;p&gt;Thad and Gavin mostly added their graphics and audio assets into the Unity project themselves. That saved me a lot of work, though in retrospect, I wish I had exerted a little more control. I didn't do a good job upfront of specifying file formats, compression parameters, etc., so I had to go back and edit a lot of those files and their import settings to bring the build size below the 150 MB that Google Play allowed. (Converting dozens of icon and texture files one by one in GIMP to be square powers of two to optimize compression isn't my idea of a good time.) And as much as I appreciated not having to lay out all of the user interface, I did have to reimplement a lot of it to adapt to different aspect ratios, support programmatic manipulation, and keep everything consistent.&lt;/p&gt;
&lt;h2&gt;Demoing and playtesting&lt;/h2&gt;
&lt;p&gt;During most of DTMB's development Thad and I lived in New York City. (I then moved to Cincinnati, Ohio.) I often went to the indie game expos hosted by &lt;a href="https://playcrafting.com/"&gt;Playcrafting&lt;/a&gt;, and we decided to exhibit DTMB at their Winter Play event in 2019. It gave us good motivation to reach a certain level of completion, and it was a lot of fun! We set up a table with a couple mobile devices with the game installed, and had several people play it, subtly watching over their shoulders. It was the first time we had a lot of people trying it. Their response was encouraging; people would keep hitting continue after game over to play again. We also learned what aspects of the game were confusing, and how difficult the game was for a general audience.&lt;/p&gt;
&amp;lt;figure&amp;gt;
    &amp;lt;img src=&amp;quot;/assets/optimized/posts/2023-02-08-dtmb-retrospective-pt-1/winter-play.jpg&amp;quot; alt=&amp;quot;An attendee at Playcrafting's Winter Play event&amp;quot; /&amp;gt;
    &amp;lt;figcaption&amp;gt;Demoing Don't Take My Beans! at Playcrafting's Winter Play 2019 event in New York City.&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;p&gt;In March 2020 (when people suddenly had lots of time on their hands) we released a closed beta version to a handful of friends, family, and colleagues, via Google Play internal testing for Android and &lt;a href="https://testflight.apple.com/"&gt;TestFlight&lt;/a&gt; for iPhone. Derek Yu has a good article about &lt;a href="https://derekyu.com/makegames/feedback.html"&gt;soliciting feedback&lt;/a&gt;, and this was what he classifies as sympathetic feedback, so not quite unfiltered. But one thing became clear: the game was still too hard. To address this we added power-ups randomly dropped by defeated enemies, and an inventory system for items purchased with in-game currency (thinly disguised as &amp;quot;forging&amp;quot; items with gold gears representing collected scrap). The currency had the added benefit of feeding into the monetization; we included optional rewarded ads that, when viewed, allowed players to double the currency collected during a run. I also updated the difficulty progression to adjust dynamically between runs—slower for players who died often to ease frustration, and faster for players who did well to prevent boredom.&lt;/p&gt;
&lt;p&gt;I could see how well the game retained players from the telemetry collected via &lt;a href="https://unity.com/products/unity-analytics"&gt;Unity Analytics&lt;/a&gt;: our beta testers weren't playing for very long. So we changed the game's level-based progression (collect a certain number of bean cans to unlock the next difficulty level) to a high score system, hoping players would care more about beating their last score (and with the eventual goal of an online leaderboard). And we tied continuing to a sort of wager system—spend half the bean cans you've collected in the run to continue, in the hope you can do even better, but risking your current spot on the top score board. (Players could of course also watch a rewarded ad to continue, once per run.)&lt;/p&gt;
&lt;h2&gt;Early access&lt;/h2&gt;
&lt;p&gt;A year later, in March 2021, we launched in early access to the public. Several fixes and adjustments happened during this time. (Many thanks to everyone who tested, and a major shout-out to &lt;a href="https://bitwesgames.com/"&gt;Butch Wesley&lt;/a&gt; in particular for extensive, thorough feedback.) I also overhauled the Jesdo Software &lt;a href="https://www.jesdosoftware.com/"&gt;website&lt;/a&gt;, because Unity Ads &lt;a href="https://docs.unity.com/ads/en/manual/app-ads-txt"&gt;required an app-ads.txt file hosted on the developer site&lt;/a&gt;, and the &lt;a href="https://wordpress.com/"&gt;WordPress.com&lt;/a&gt; plan I had didn't support hosting a plain text file. That site was also ugly and hard to make look how I wanted, and remaking it helped me catch up on web development for the day job. I'm proud of how the new site turned out, especially on a technical level, and plan to write a blog post about it. But it was a major distraction that pushed DTMB's development out even further.&lt;/p&gt;
&lt;p&gt;Toward the end of the early access period I had second thoughts about monetizing via rewarded ads, worrying it was too pay-to-win (&amp;quot;paying&amp;quot; in this case with the time spent watching the ad). So I replaced the rewarded ads with skippable interstitial ads that played between every few runs, and added a small, one-time in-app purchase to remove them. I felt this was fair to everyone—paying only removed the ads and conferred no other bonus, and was in line with how e.g. streaming services run ads. But, in another example of how the whims of platforms can cause great harm to small devs, Google &lt;a href="https://support.google.com/googleplay/android-developer/answer/12253906"&gt;decided to no longer allow &amp;quot;unexpected&amp;quot; interstitial ads&lt;/a&gt;, right after all that work to change them! To ensure compliance with the new policy, I changed the ads back to optional rewarded ones, though only to continue after dying, as the ones for doubling collected currency never saw much use. I also kept the in-app purchase for removing ads, which gave the player a &amp;quot;free&amp;quot; continue per run. (So even more pay-to-win than before, oops.)&lt;/p&gt;
&lt;h2&gt;Next, in part 2: the production release&lt;/h2&gt;
&lt;p&gt;That's it for part 1 of the Don't Take My Beans! retrospective! In part 2 I'll write about how the production release went, adventures in advertising, and how I plan to approach future projects. For notification when I post part 2, subscribe to &lt;a href="http://eepurl.com/dK8itw"&gt;our mailing list&lt;/a&gt; or to our &lt;a href="https://www.jesdosoftware.com/rss.xml"&gt;RSS feed&lt;/a&gt;, and feel free to reach out on &lt;a href="https://mastodon.gamedev.place/@JesdoSoftware"&gt;Mastodon&lt;/a&gt;, &lt;a href="https://twitter.com/JesdoSoftware"&gt;Twitter&lt;/a&gt;, or &lt;a href="mailto:jesse@jesdosoftware.com"&gt;email&lt;/a&gt;. Thanks for reading!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Part 2 of this retrospective is now available &lt;a href="https://www.jesdosoftware.com/posts/2023-02-11-dtmb-retrospective-pt-2"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
            <pubDate>Wed, 08 Feb 2023 13:39:00 GMT</pubDate>
        </item>
        <item>
            <title>Don't Take My Beans! post-release retrospective, part 2: release, advertising, and platform woes</title>
            <link>https://www.jesdosoftware.com/posts/2023-02-11-dtmb-retrospective-pt-2</link>
            <guid>https://www.jesdosoftware.com/posts/2023-02-11-dtmb-retrospective-pt-2</guid>
            <description>&lt;p&gt;&lt;img src="https://www.jesdosoftware.com/assets/optimized/posts/2023-02-11-dtmb-retrospective-pt-2/dtmb-logo.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is part 2 of a retrospective/postmortem for our game &lt;a href="https://www.jesdosoftware.com/dtmb"&gt;Don't Take My Beans!&lt;/a&gt; Read &lt;a href="https://www.jesdosoftware.com/posts/2023-02-08-dtmb-retrospective-pt-1"&gt;part 1 here&lt;/a&gt;. You can download Don't Take My Beans! for free from &lt;a href="https://play.google.com/store/apps/details?id=com.jesdosoftware.donttakemybeans"&gt;Google Play&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As I mentioned in &lt;a href="https://www.jesdosoftware.com/posts/2023-02-08-dtmb-retrospective-pt-1"&gt;part 1&lt;/a&gt;, development of Don't Take My Beans! took a few years, due to being our first major game development effort, and being done in our spare time. In my case that spare time was becoming more and more of a luxury, having gotten married in 2019 and then a baby due in fall 2022. Engagement and retention with each early access release were low, a problem I could never solve, and while I wanted our efforts to have the best chance of success as possible and still had ideas I wanted to implement, the time had come to ship.&lt;/p&gt;
&lt;p&gt;We had developed DTMB for both Android and iPhone, but Thad and I used Android on our primary devices, so the Android version got a little more love. Plus, releasing a production version on Google Play wasn't much different than releasing a beta version—the store page was already up. So we launched on Google Play first, planning the iPhone launch for shortly after. It went live on July 26, 2022.&lt;/p&gt;
&lt;h2&gt;Adventures in advertising&lt;/h2&gt;
&lt;p&gt;One of the main pieces of advice given to indie devs is to build a community around your game during development. But since this was a simple free-to-play mobile game, there wasn't much of a community to be had. Rather, as I learned well after the decision to make a mobile game, user acquisition for mobile games consists mainly of paid advertisement. The process is a ruthlessly efficient machine of spending on ads, tracking ad conversions, calculating how much each acquisition cost versus how much you earn back, and iterating tirelessly on ads and monetization to ensure you make a profit. (See &lt;a href="https://www.pocketgamer.biz/feature/78246/the-mobile-games-industry-glossary/"&gt;PocketGamer.biz's mobile games industry glossary&lt;/a&gt; for a helpful survey of all the terms involved, and &lt;a href="https://lancaric.me/user-acquisition-creative-learnings-2022/"&gt;this article by Matej Lancaric&lt;/a&gt; for a look at how complex and challenging it all is.) Not exactly what I thought I was signing up for.&lt;/p&gt;
&lt;p&gt;But we'd come this far, and we were barely getting any organic installs, so I gave paid advertisement a shot—with a firm cap on how much I was willing to spend.&lt;/p&gt;
&lt;p&gt;I went with &lt;a href="https://ads.google.com/"&gt;Google Ads&lt;/a&gt;, because it seemed to have good reach with people who might like our game, and it integrated well with Google Play for tracking conversions. They also gave an ad credit if you spent a certain amount, doubling how much I could spend. The only creative we had on hand was the trailer Thad had made, and we didn't have the bandwidth to produce any more, so I just ran the trailer.&lt;/p&gt;
&lt;p&gt;These were the results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conversion rate: 11.43%&lt;/li&gt;
&lt;li&gt;Installs: 1,700&lt;/li&gt;
&lt;li&gt;Cost-per-install (CPI): USD 0.59&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A little expensive, but people were finally playing the game!&lt;/p&gt;
&lt;p&gt;So how much did we earn back?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sigh.&lt;/em&gt; USD 6.33. All from the rewarded ads to continue after game over; none from the in-app purchase to remove the ads.&lt;/p&gt;
&lt;p&gt;So, not exactly worth it. Once I used up the free ad credit, I ended the ad campaign.&lt;/p&gt;
&lt;h2&gt;Abandoning Apple&lt;/h2&gt;
&lt;p&gt;Unlike Google Play, releasing an early access/open beta version on iPhone involves publishing via &lt;a href="https://testflight.apple.com/"&gt;TestFlight&lt;/a&gt;. It's a little more cumbersome for end users, because they need to install the TestFlight app, but they can at least access the app to test via a public link.&lt;/p&gt;
&lt;p&gt;TestFlight doesn't have store pages or marketing assets like the App Store does. This is nice during development because you can publish before you have all those assets ready. But when it came time to publish DTMB on the App Store proper, it turned out the screenshots and trailer we'd prepared for the Google Play store page didn't meet the resolution and aspect ratio requirements for the Apple App Store (which mirror the latest iPhone models). Not an insignificant amount of work to redo all those, especially the trailer. By this point, my son had been born, and DTMB was performing poorly on Android. I couldn't justify the time and level of effort, so I &lt;a href="https://www.jesdosoftware.com/posts/2022-12-10-iphone-release-postponed-indefinitely"&gt;postponed the iPhone release indefinitely&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Google gotcha&lt;/h2&gt;
&lt;p&gt;Meanwhile, in September, I tried to disable the open testing track, to prevent users from accidentally downloading an old version of the app. Google Play rejected that update, saying DTMB had an invalid data safety form. The specific issue they cited was that it collects and transmits apps on the device but that the data safety form doesn't report such. I had done a thorough review of &lt;a href="https://web.archive.org/web/20220930091725/https://docs.unity.com/ugs-overview/GoogleDataSafety.html"&gt;Unity's documentation for Google's data safety form&lt;/a&gt;, and none of their frameworks I used said they collected apps on the device. It was also weird I got that notice after just disabling the testing track; the update included no changes to the app. Figuring it must have been a glitch, I submitted an appeal, including Unity's documentation on the matter and asking for clarification on what they saw that got flagged.&lt;/p&gt;
&lt;p&gt;Their response? The exact same message, with no additional details.&lt;/p&gt;
&lt;p&gt;So I used &lt;a href="https://support.unity.com/hc/en-us/articles/115002917683-Using-Charles-Proxy-with-Unity"&gt;Charles Proxy&lt;/a&gt; to inspect the outbound traffic myself. I found nothing related to other apps on the device. I replied to their message with the logs I collected, and asked again for clarification on what they saw.&lt;/p&gt;
&lt;p&gt;Same exact message in reply. I don't think a human being reads these.&lt;/p&gt;
&lt;p&gt;So that's yet another impediment to pushing further updates, in addition to what I mentioned in &lt;a href="https://www.jesdosoftware.com/posts/2023-02-08-dtmb-retrospective-pt-1"&gt;part 1&lt;/a&gt;. I'm thankful at least they didn't pull the app outright, at least not yet. I suppose I could update the data safety form to say apps on the device are collected, but as far I as can tell, that just isn't true. So 1.0.7 will probably be the last version of DTMB that Google Play sees.&lt;/p&gt;
&lt;h2&gt;Where to from here&lt;/h2&gt;
&lt;p&gt;Thus the tale of Don't Take My Beans! concludes with a disappointing whimper. Would I do it all again? Yes, but differently, haha. There's not much to show for our efforts, but I learned a lot, I had fun, I'm proud of what we made, and we actually released a game, which not many can say.&lt;/p&gt;
&lt;p&gt;My main regrets include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spending so long on development, at the expense of other ideas I want to work on&lt;/li&gt;
&lt;li&gt;Entering a market (in this case, free-to-play mobile games) before understanding the space and its norms and challenges&lt;/li&gt;
&lt;li&gt;Not gathering feedback earlier in the process, and not working harder to understand that feedback to make more impactful adjustments&lt;/li&gt;
&lt;li&gt;Relying on platforms that have zero reason to care about my experience or success, without a contingency plan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I doubt Don't Take My Beans! will see any further development. At one point I got halfway through getting a WebGL build ready; perhaps one day I'll finish that and throw it up on my website and/or &lt;a href="https://itch.io/"&gt;itch.io&lt;/a&gt; or something, in the name of software preservation.&lt;/p&gt;
&lt;p&gt;For future projects, I'll likely target PC/Steam first, which I've been learning a lot about, perhaps with mobile adaptations if things go well. I'll attempt smaller, simpler projects, and get them in front of people as fast as possible. And I've enjoyed my experience so far with &lt;a href="https://godotengine.org/"&gt;Godot&lt;/a&gt;, so I'll see how far that takes me.&lt;/p&gt;
&lt;p&gt;Now, with this experience gained and lessons learned, it's on to the next game!&lt;/p&gt;
</description>
            <pubDate>Sat, 11 Feb 2023 16:03:00 GMT</pubDate>
        </item>
        <item>
            <title>Mailing address changed</title>
            <link>https://www.jesdosoftware.com/posts/2025-04-03-address-change</link>
            <guid>https://www.jesdosoftware.com/posts/2025-04-03-address-change</guid>
            <description>&lt;p&gt;Just a quick note to mention we've updated our mailing address. Both our &lt;a href="https://www.jesdosoftware.com/privacy-policy"&gt;privacy policy&lt;/a&gt; and &lt;a href="https://www.jesdosoftware.com/dtmb/eula"&gt;the end-user license agreement for Don't Take My Beans!&lt;/a&gt; have been updated to reflect the new address.&lt;/p&gt;
</description>
            <pubDate>Fri, 04 Apr 2025 02:46:00 GMT</pubDate>
        </item>
    </channel>
</rss>