Categories: Devlog | Game Design | Game Development | News | Retrospective | Technical | Web Development |
  • Publishing Godot Games to Steam for MacOS without Hardware

  • Technical · Godot MacOS · 2022-07-22 · nightblade
  • Godot and Mac

    Are you working on a Godot desktop game? Would you like to publish it to MacOS, without the pain of learning about MacOS-specific requirements like signing, notorization, and paying $99/year?

    The good news is, if you plan to publish your game on Steam, you can easily do this, without Mac hardware. My inspiration for this is: be the change you want to see in the world. Publish your game for Mac (and Linux), so the market grows, and more great games support these OSes.

    If you're interested in how to do this, skip the section below; if you're interested in how this all works (sort of), the next section gives a very brief overview of the problem.

    Preamble: Signing, Notarization, and DMG Files

    I don't pretend to understand how all this works. My understanding, as someone who mainly uses Unix and Windows, is the following:

    • Like Windows, Mac OS requires developers to "sign" their apps with a cryptographic key of some sort
    • Unsigned apps previously run on Mac OS with a warning; as of writing (2022 June), they no longer run at all.
    • Notarization is a more scrutenized form of signing, and requires sending your app to Apple to approve
    • DMG files are native to Mac, and internally contain an .app file

    The key thing here: the DMG contains an .app "file" (looks like an executable on MacOS), which is actually a zip file. That zip contains your actual binaries.

    MacOS and Steam

    Follow these steps:

    • Create a new export profile for Mac. Configure as you like (e.g. exclusion files)
    • On a non-Mac system, export your project for Mac. If you're using the CLI, make sure you speify the output file name as a zip file (e.g.
    • Verify the zip contents: it should have a directory (with Game replaced with your game name) at the root, with a Contents subdirectory
    • Upload that zip to Steam
    • Set up your launch options. According to the current Steamworks docs, for MacOS, your Executable should be set to (replace Game with your actual game name / folder name).

    And that's it! If you launch the game on Mac, it should just work!

    Finally: I recommend you always make sure someone with Mac hardware tests your game to ensure it launches correctly. If you don't have a friend with a Mac, you can always ask me on Twitter or by email to try it out.

  • Gem Worlds Terrain Update

  • Devlog · Gem Worlds · 2022-07-13 · nightblade
  • demo screenshot

    Hello! I made lots of changes to Gem Worlds over the last couple of months, based on player feedback that the game could use more interesting interactions between things in-world.

    Based on that, I added a few terrain types to the game; they generate in each world:

    • Teleporters: previously existed, but now exist in every world
    • Light Stars: they move back and forth, even through dirt tiles
    • Receeding blocks traps: once you step on them, they pop up into walls for a few turns, then reset

    I also added, then scrapped, a couple of terrain:

    • Pipes, which move you from one spot to another (inspired by Supaplex's pipes)
    • Conveyor belts, which constantly move everything on them

    Conveyor belts added a lot of interesting dynamics to the game. Unfortunately, they also contributed a disproportionately huge amount of bugs. In the end, I scrapped them.

    Meanwhile, they also exposed a huge performance issue, where moving caused a drop of ~130ms (roughly ten frames). Fixing this required ripping out and rewriting the main collision-detection system, which resulted in an explosion of bugs, and took way too many weeks to fix. Alhamdulillah, those are all fixed now.

    I also added (again based on played feedback) keys and locks! In every 5th and 10th level of each world, the exit appears from the start, but lock blocks surround it; you need to find one (or three) keys to unlock them and exit.

    I'm looking forward to shipping a new v0.5.0 demo soon inshaAllah, and getting (and integrating) more feedback and features into the game. When that ships, I would really appreciate it if you could give it a quick play-through, and let me know your thoughts.

  • Gem Worlds Demo, MacOS Support

  • Devlog · Gem Worlds · 2022-05-12 · nightblade
  • demo screenshot

    Despite not working much on Gem Worlds during Ramadan, I'm very happy to announce:

    • Gem Worlds participated in the Steam Going Rogue festival. This resulted in a huge visibility boost (around 50k visits in a week).
    • As part of that, I launched the Gem Worlds demo. While the fesitval is over, you can still play the demo here
    • I finally have access to Mac hardware to develop and test my games. Accordingly, I launched the Mac version of the Gem Worlds demo, too.

    Based on feedback from a couple of players, I changed a number of things in the game; most notably: - I added keyboard bindings and fixed tooltips for all skills and items - You can change sklils at any time, by quitting to the skill shop (you resume back from the same level afterward).

    While this resulted in lots of people looking at Gem Worlds, it resulted in a mere ~30-ish downloads. This confirms one of my hunches from a few months back: the core game itself isn't that interesting or captivating. Based on the feedback I received from a couple of players, despite being designed as "play, die, retry with different skills," the replayability and interest in continuing through the game is minimal or zero.

    This dramatically hurt my motivation to work on the game. It's the biggest game I've ever made (by at least 50%). Regardless, my plan is to inshaAllah continue slogging through the leftover work to get the game out.

    At this point, I may not run a beta version, either; that requires at least a significant amount of players (new and recurring), which I didn't get access to. I'll provide updates on that as development continues.

  • Using Feature Toggles to Keep your Demo Code Up-to-Date

  • Game Development · 2022-03-28 · nightblade
  • One of the problems we run into as game developers, is keeping our game demos up-to-date. Data suggests that keeping your demo up longer results in more wishlists and sales; but how do you manage keeping your demo up-to-date with your game as it changes (including copying over bug-fixes)?

    Most developers opt to keep a separate branch/version of demo code, and manually keep that up-to-date. As the game and demo code diverge more and more, porting over changes and bug-fixes becomes a bigger and bigger headache.

    Instead, I proprose another solution: using feature toggles to keep your demo separate. This way, you keep a single code-base for your demo and production game. (You can read about feature toggles in Fowler's execllent, comprehensive guide.)

    How this works:

    • You add a feature toggle for something like "is_demo" or "demo_content"
    • You gate as much content as possible behind the toggle
    • You publish two versions of your game: one with the feature (demo) and one without (full game)

    Benefits of this approach:

    • Main game and demo are always in synch: you can easily change what's in the demo (levels, skills, etc.)
    • Any bug-fixes in the main game, for bugs that are present in the demo, get fixed in the demo for free.
    • Requires minimally-invasive changes in your game to create the demo version

    The main drawback of this approach, is that your demo includes all the content and functionality of the actual game. While this means you can easily do things like switch which skills and levels are available to the player, it also adds the possibility of someone reverse-engineering your demo and getting full access to your game. If you're not okay with that, I suggest you look at other approaches.

    Gating Content

    Depending on your language/engine of choice, you either gate content behind pre-processor statements (e.g. #if DEBUG) or regular if-statements (e.g. if Features.IsDemoMode == true).

    I can't stress this enough: it's really important to learn from "defense in-depth" and gate as much as you can. You want to protect your game from technically apt adversaries who can decompile/reverse-engineer it and gain access to the full game.

    To do this, add checks absolutely everywhere possible. For something like Gem Worlds, this means adding checks in the skill shop, in the core game (when a level loads), on the title screen (continuing a game but you're past the end of the demo?), etc.

    For additional security, if possible, store content and data in JSON/external files, and use your editor to switch which of those files is used in the demo. (e.g. if your skills are stored in skills.json, maybe you have two versions - skills.json and skills-demo.json - and can switch which one is used in the demo build.)

    While this is game-specific, the more checks you add, the better; not only do you reduce the chance of accidentally giving players access to the full game, but you also make sure that there's no way for them to break out of the demo content.

    The other problem with gating using feature toggles, is that it really requires additional testing of the final build. Try your game, play through to the end; then put on your attacker hat, and try to circumvent the restrictions. Can you edit the save files and get inaccessible skills, or go past the last part of the demo? Make sure you test until you feel comfortable that it's bullet-proof.

    If all else fails, platforms like Steam allow you to remove/disable the binaries (and in Steam's case, it yoinks the files away from the user's system). You can always rely on that in case things go bad.

    Publishing Two Versions

    Finally, constructing the demo build. Many programming languages since C/C++ allow you to define build-time constants, and specify build profiles. This includes C/C++, C#, Java, and others. I will focus on Godot/GDScript, since that's my current stack of choice.

    As of Godot 3.4, you need to:

    • Launch the export dialog (Project > Export ...)
    • Create a second export option for each platform you support (e.g. Windows, Linux)
    • Click on the Features tab
    • Under Custom (comma-separated), add your feature, e.g. demo_content
    • Profit

    (The same steps apply to other game engines, like Unity, MonoGame, etc.)

    Once that's done, viola, you have two separate builds - demo and non-demo. Make sure you test thoroughly!

    Closing Thoughts

    This blog post illustrates one way to create demo builds, that are always in synch with the main game content. It's not the best approach or the worst, simply one approach you can choose. While it ships the full game along with the demo, with defense in-depth, you can be quite confident that players can't access anything they shouldn't.

    If you have any thoughts or alternative approaches, hit me up on Twitter or Discord, I would love to know of a better way to achieve this.

  • Gem Worlds: March Update

  • Devlog · Gem Worlds · 2022-03-25 · nightblade
  • Hey all, just wanted to drop a quick note and let you know that Gem Worlds is pretty much content-complete. You can play the game from start to finish, and aside from some bugs and missing polish, the game is done.

    For the next couple of months up to the release, the plan is to add missing polish (like sound design, story events, and an ending) and find/fix bugs. There won't be much to show, but it's critical work.

    On the bright side, I am also planning to launch a demo of Gem Worlds. The demo will remain up-to-date with the rest of the game (it won't lag behind in terms of features or fixes), and I hope many of you will play it and pass along your feedback.

    In summary, the roadmap for the next few months (other than Ramadan, which is most of April and won't include much/any gamedev) looks like:

    • Add sound design, story events, options, etc.
    • Launch the game demo
    • Add polish and fix bugs
    • Repeat until the game is ready for beta testing