• Gem Roguelike: August 2021

  • Devlog · Gem Roguelike · 2021-09-03 · nightblade
  • What happens if you take a classic gem-collecting boulder-dodging action puzzle, make it turn-based, and add in roguelike elements like skills, monsters, and procedurally-generated levels?

    This:

    This is a prototype (mostly getting game systems working with placeholder or simple art) which I toiled away at for the last 30 days. Currently, it includes almost all the core systems:

    • Collect gems, dodge boulders, and make it to the exit without dying
    • Environmental elements to avoid, like explosive falling mines and lava pools
    • Procedurally-generated levels (five completely different level types)
    • Monsters, melee fighting, and two skills: an explosive fireball, and a stopwatch that lets you stop time for five turns.

    What's missing? My favourite roguelike element: the ability to spend gems to buy permanent upgrades and unlock new skills.

    My current vision is something like a cross between Boulder Dash and Hades. You pick from an assortment of unlocked and upgraded skills, make a run, die, upgrade and pick an entirely different set, and try again. I planned 100 levels across ten different biomes, each with their own unique set of monsters and environmental dangers to deal with.

    If you like what you see, sign up to our Revue newsletter to get weekly updates! In the coming days, you will also get instructions on how to access the playable prototype of the game!

  • A Practical Guide to Make Your Own Game Engine

  • Game Development · 2021-07-23 · nightblade
  • Want to make games faster, bigger, and with better quality, while investing the same amount of time? It's possible, albeit with an unintuitive solution: a custom game engine. I'm here to tell you why you can, and should, build a custom game engine.

    It's 2021, and lots of strong, general-purpose game engines abound: from Unreal to Godot to GameMaker to Construct, tools exist for beginner and experienced developers alike. Why bother making your own game engine?

    It's a great learning tool, sure, but a better reason exists: you can customize your game engine to your own personal style and workflow.

    A great example of this is RPG Maker, which specializes in making JRPG games. Using RPG Maker, you can - very quickly, and without much coding skill - create large-scale and complex JRPGs. RPG Maker includes events for all kinds of common JRPG things (dialog, shops, inns, quest NPCs, etc.) which makes it very, very fast to build, compared to building something from scratch.

    Even if you think this isn't a great idea, I guarantee you will learn a ton by doing this. If you're convinced, read on.

    Pick a Small Target

    You're not planning to build a general-purpose, large-scale game engines. Those are difficult, and require lots of different skillls which you may not have.

    First, identify an existing game engine, framework, library, toolkit, etc. that you use and like. What's great about it? Importantly, what's not good about it? Where can you improve upon it, or what pain-points does it inflict on you that you wish you could work around?

    Once you identified your starting-point, you can even build on top of an existing game engine. This way, you create a standalone library, or a thin "layer" that makes some tasks easier. It could be as simple as scene management, or as complicated as common code for a roguelike.

    Whatever your goal, pick something small and achievable as the first step.

    Pick a Companion Game

    Now, the most important part: do not build your game engine or framework in isolation! You will end up with bloated features that are difficult to use, and code that nobody uses. Instead, design a small standalone game that you feel really excited to build.

    The key: build your game in tandem with your game engine. For example, if you need outlined text, add some code for that to your game engine, then add it to the titlescreen, options screen, or whatever location in your game that you need it.

    This keeps your code useful, streamlined, and well-tested to begin with; it greatly increases the chances that you can ship something useful at the end of your game development cycle, whether the game ships or not.

    Work on your game framework with that cycle: add code, test it, implement it in your game. Rinse, repeat.

    Use-Case

    If your game framework extends beyond a simple library, you should consider the user workflow carefully. How do users use your framework? Do they link a DLL, or copy/paste code into their project? Do you need to provide a template project with some starter code, or simply a spec for a JSON file?

    Looking at this early on makes it easier for users to eventually use your game framework.

    Testing and Quality

    Testing your game framework is really important. As it grows, you will find it increasingly likely that you accidentally break things in other places and not notice. I highly recommend writing unit tests and/or integration tests for every single line of code you write. This makes it very easy to make changes: you simply run the tests, and they identify anything broken you need to fix.

    A War Story: Oneons and Puffin

    I applied this process to a number of game frameworks over the years (mostly abandonware). One of them, Puffin, actually shipped to production (I finished it and launched the game and the framework). It didn't meet my long-term needs, but it worked well enough.

    Here's a quick summary of how that came to be:

    • Target: I really like Godot. One thing that frequently bugs me is the lack of free support for exporting your game for the Nintendo Switch. I'm also not a big fan of GDscript, the internal, Python-like scripting language.
    • Goal: I decided to build something similar to Godot - a visual IDE - albeit in C#. I chose MonoGame as my base, since I've used it before, and since it has excellent free support for porting to the Switch
    • Small Target: For the first version of Puffin, I decided to leverage my experience with CraftyJS and build a small, easy-to-use fluent API. I based it on Entity-Component System architecture. (This isn't a good fit for Godot-like games, which use nested nodes.)
    • Start Small: I build the absolute minimum code to get started: a base entity class, and some components for rendering sprites and text. That's it. I decided I would limit myself to no IDE or UI controls, as those require a lot of additional effort to build.
    • Companion Game: I started immediately on Oneons, my companion game: a tiny broughlike dungeon-crawler with 12 floors of mayhem, monsters with powers, and tactical combat. I shipped the first version of Oneons, with Puffin, in a month for the Persistent Game Jam.
    • Unit testing: Most of the Puffin code is unit-tested, and every commit builds and runs the test in Jenkins. This helped me notice when I accidentally broke things.

    Ultimately, Puffin didn't meet my needs; in particular, the choice of an ECS architecture didn't mesh well with Godot-style nested scenes and subscenes.

    I may revisit Puffin in the future, and I certainly learned a lot about development through this experience. I hope you, too, will find the time and effort to build something, big or small, to help you build games you like faster and better than whatever you're using today.

  • Crystal Caverns March Update

  • Devlog · Crystal Caverns · 2021-03-29 · nightblade
  • Introducing Crystal Caverns, a match-3/roguelike hybrid with persistent upgrades. In the last two months, I took this game from a rough prototype to what you see in the video. At present, the game includes:

    • A bare-bones battle system: players and monsters take turns attacking.
    • A basic match-3 game with collapse mechanics, albeit you can swap any two tiles
    • Victory and defeat
    • Persistent currency (crystal shards) which you retain across battles

    Battles appear bare-bones at the moment, but include some depth: - Players can attack, critical-strike, boost defense, poison enemies, drain, and heal. - Monster attacks affect the board in various ways (currently, they just eat random tiles).

    That includes enough of the core game to improve upon.

    Next month, I plan to turn my attention more towards the roguelike side of the game: generating dungeons with monsters, finding treasure (including persistent treasure), and balancing exploration with progression.

  • Blog Reboot

  • News · 2021-03-18 · nightblade
  • sign that says: changes ahead

    Hello! Long-time readers of this blog may notice a couple of changes:

    • A new, mobile-responsive theme
    • A complete restructuring of content

    I decided to redo the blog to make it mobile-friendly, and to hange the content - instead of game development notes and game design articles, instead, I plan to focus on my games.

    What can you expect going forward? Weekly posts show-casing the best of whatever current project I'm working on.

    Old articles will stay available for a while.

  • Web Application Translation Architecture in .NET

  • Other · 2020-08-11 · nightblade
  • Tags: .NET Core, Architecture

    globe of languages

    So you want to localize and internationalize your web application? There are a lot of considerations, but here, we briefly discuss just the translation part.

    This post covers a couple of the architectural/design options and discusses their respective trade-offs. While this is a bit specific to .NET, other languages no doubt provide similar concepts, with various levels of API support (e.g. language stored in cookies)

    Individual Translations via RESX Files

    .NET and .NET Core provide some infrastructure called "resource files" (.resx) extension). These are XML files which you can edit directly in Visual Studio; at runtime, they compile down to a binary format. They generally recommend creating a few resource files (one per back-end controller or shared module). Advantages of this approach include:

    • Easy editing of the file (in-IDE)
    • Easy versioning/history of the file (it's a text format)
    • API support for configuring the prefered language in a cookie, etc.
    • Localized changes on translation change (no need to re-test everything)
    • Efficient, with a small size at runtime

    The disadvantages of this format include:

    • Any translation change requires recompiling the entire application
    • Editing dozens of files can be very cumbersome
    • Difficult to make a translation change and see it immediately in-app (unless you're a developer)
    • You can't store any sort of metadata (e.g. notes) with translations

    Overall, I think this approach works well if you plan to update translations periodically and don't need an external translater. (If you do, and they're not a coder, you'll need to make additional tooling to export/import the strings in a format they can understand.)

    Using a Database for Translations

    One common alternative approach is to store the translations in a database (relational or otherwise) and simply load/display them at runtime. This confers some additional advantages over resource files:

    • Ability to update a translation and instantly see the change in-app
    • Ability to store meta-data (like notes) with each message
    • You can quickly query to find missing strings in various languages
    • Non-technical users can easily edit translations via a simple web UI

    However, it contains some additional downsides:

    • You need to write a web UI to allow translators to be able to view/update translations
    • Making several database calls just to load one view/page, can be costly in terms of performance
    • You can read/cache strings in memory on app-start, but then your app requires additional memory per language

    I think this approach suits situations where you absolutely must be able to see updated translations reflected immediately, or where you have non-technical translators who need an easy way to be able to update translations.

    If you know of any other architectures/designs, drop me a note on Twitter and let me know!