Author Archives: Sébastien Bénard

  1. Dumber Dwarves

    Leave a Comment

    Dumber Dwarves is a dungeon crawler where you can’t control the adventurers directly and they are not the sharpest tool in the shed. Slap them or throw some meat on the battlefield to give your “instructions”.

    The game was created in 48h (well, more like 35h) for the GMTK 2020 game jam. The theme was “Out of Control“.

    Please note that there is no sound nor music in this game. Didn’t have time :)

    Trivia

    The game first started as a god game where you were to teach humans things by only slapping them. So, if a disciple was picking up some food for example, slapping him would teach him to avoid food (ie. “god thinks food is bad“). Problem was: a disciple who learn something tends to repeat the concept on its neighbors. So, someone who thinks food is bad will also slap other disciples picking it. It was even possible to slap someone slapping, so it would teach that slapping someone was bad. And so on :)

    It was a funny little prototype, but too sandboxy to actually become an interesting jam game. Maybe with some extra work, but definitely not in 48h.

  2. Roadmap

    6 Comments

    Going rogue, part 2

    Hi everyone!

    TL;DR: you can simply check the roadmap at the end of the article.

    First of all, let me thank everyone of you ​for your amazing support :) I received many very touching messages which were really important to me (and actually balanced the total lack of support I received from my former team mates at Motion Twin). I’m now really motivated to prove worthy of your confidence.

    Moving forward, I’m now officially a game company, called Deepnight Games

    Some of you might notice the tiny red star on the character shield ;)

    I’m now legally allowed to make, publish and hopefully earn money from games.

    L-Ed / RPG Map

    Aside from all the administrative stuff, one of the first things I did was to work on a 2D level editor for game-devs, based on my experience with RPG Map 2, code named L-Ed (for Level Editor). It’s not released yet at this point, but should be out there really soon, probably open-source. I will talk about this one a little bit more in a future article.

    This project, plus the whole Covid-19 thing obviously had a few impacts on the development of RPG Map 2. My time was very limited and it was impossible for me to invest as much time I would have loved to on RPG Map. This means the Update 17 was delayed a lot: it’s still planned, just without any estimated release date yet.

    Roadmap

    So here are my general roadmap for the next few months. Please note the timeline may vary: some events might occur before some others, depending on the time I’ll actually have and the progress made.

    L-Ed release
    Game-dev oriented 2D level editor, free and probably open-source
    RPG Map (Steam release)
    Not much to do here, except a few bug fixes, and me getting used to the Steam publishing workflow.
    RPG Map update 17
    This is a big one. I plan to rework completely the UI using what I’ve learned from making L-Ed (basically: using NodeJS). This will allow the app to become completely cross-platform: Mac & Linux support is coming!
    My first game as a solo dev
    Top secret stuff for now, but I’m quite excited :)
  3. Part 4 – Localize texts using PO files

    4 Comments

    GetText

    About

    PO files are part of the GNU GetText localization technique. It’s a very simple format that can be edited using various tools, like POEdit (available on Windows, Mac & Linux).

    The philosophy

    The “classic” way to do things is to write “dev English” sentences in your code, then use this Dev-English to kind-of translate to “proper English” (which will be used in the release version of your game), or translated to “proper whatever-language” you might want.

    Note that your Dev-English are the keys for the translation texts. So changing your Dev-English texts will break the keys. The good thing is POedit handles that well, and properly suggests “lost” translations.

    My implementation

    My GetText implementation has 3 elements:

    If you want to use the GetText lib for Haxe, you will need to install it:

    haxelib install deepnightLibs

    Usage

    Marking translatable strings with Lang.hx

    In your code, just use calls like: Lang._("Some translatable sentence"). This will allow our tools to extract all the strings that require some translation, so we can feed our PO tool.

    For example:

    function myStuff() {
      trace("This is an untranslated text");
      trace( Lang.t._("This text is meant to be translated, and will be extracted.") );
    }

    Extracting texts

    You can run haxe langParser.hxml from the command line to extract all strings in Lang.t._(...) calls.

    All these strings will be stored inside a POT file, which is a Catalog file.

    Using POedit to translate

    In my above example, the POT file is my “Dev-English” string catalog. It should be stored it in the /res/lang folder.

    In POedit, start a new translation by setting the target language (could be French for example, or English again, if you want to turn your dev-English into something better).

    Import your POT catalog using the menu Catalog -> Update from POT. This will add all the untranslated strings extracted by the LangParser script.

    Translate or validate existing entries “as-is”, and save your PO file. It will also generate a MO file which is basically the optimized/binary version of the PO file.

    Import translations into your code

    Modify the Lang.init() method to import new languages. All your Lang.t._("My string that needs translation") calls will be replaced by the translated string found in your MO file on runtime.

    Important: all the PO and MO files should be stored in /res/lang folder!

    Advanced features

    Strings with parameters

    If you need some dynamic content inside a translatable string, you use the ::myVar:: system. To replace myVar in your string by the actual value you want, you need to provide an anonymous object to the Lang.t._(“…”) call.

    See the following examples:

    Lang.t._("Hello ::name::! How are you?", { name:user.name });
    Lang.t._("::v:: + ::v:: equals ::eq::", { v:5, eq:10 });

    Note that the compiler will check any anomaly here:

    Lang.t._("Hello ::name::! How are you?");
    Lang.t._("Hello ::username::! How are you?", { name:"foo" });

    Both will pop a compile error of variable name mismatching.

    Adding translator comment

    Sometimes, you may have some strings that could translate differently based on context.

    For example, in your app, you might have a setting for some font size, and one possible value is the string “Large“. In this case, it means “Big“. For another setting, like a world size, you might have a setting string “Large” again, but this time it means “Vast”. They would translate in different ways in French for example.

    To disambiguate these strings, you can use Translator comments:

    Lang.t._("Large||for a font size"); 
    Lang.t._("Large||for a level size");

    Both will return “Large” at runtime by default, but they can now have distinct translations, if needed (so the return will vary in this case).

    Warning: due to some technical limitations, you shouldn’t have ANY space around the “||” (double pipes) characters.

    In POEdit, translation comments appear right in front of the corresponding entry:

  4. Part 3 – Distributing a Haxe project

    2 Comments

    After hundreds of hours spent on your Haxe / Heaps project, you probably want to release it at some point.

    All you want in the end is a basic Executable file that you could push on your favorite distribution platform. Let’s see how we could do that.

    RedistHelper

    About

    RedistHelper is a free tool I wrote to facilitate my RPG Map redistributables creation. It makes the whole process automated and hassle free.

    Install latest stable version

    From a command line, just get the latest release by running:

    haxelib install redistHelper

    You will need my general purpose libs too:

    haxelib install deepnightLibs

    Git version

    Optionally, you can also you the latest GitHub version using the following command. Be careful though, as it might be unstable.

    haxelib git redistHelper https://github.com/deepnight/redistHelper.git
    haxelib git deepnightLibs https://github.com/deepnight/deepnightLibs.git

    Using redistHelper

    Showing help

    The most basic way to use is to open a command line inside your project root (where the HXML files are), then type:

    haxelib run redistHelper

    This will display the tool help, including some examples.

    Basic usage

    To package your project, just run:

    haxelib run redistHelper myProject.hxml

    RedistHelper will parse your HXML and create a redist folder containing all the required files. You can simply distribute that package and it should work :)

    You can package all your HXML files in one single call:

    haxelib run redistHelper gameHashlink.hxml gameJs.hxml gameSwf.hxml

    You can optionally add the following parameters to the RedistHelper command:

    • -zip : will create a ZIP archive for each package
    • -v : enable verbose mode (mostly useful for debugging)

    Embedding extra files

    You might need to add some extra files to your packages, like a README or a LICENSE. Just add their path to you RedistHelper command:

    haxelib run redistHelper game.hxml docs/README docs/license/LICENSE

    You can rename any extra file on the file by adding a “@” to their path:

    haxelib run redistHelper game.hxml docs/README@readme.txt

    Available targets

    HashLink project

    The goal here is to turn your app into classic and easy to distribute Windows Executable (EXE).

    When packaging HashLink (HL) projects, RedistHelper will copy all the required runtime files directly from the Haxe and HL folders from your system. This includes DLL and NDLL, the HL executable and a few other things.

    Your project.hl file will be renamed to hlboot.dat which is the default file loaded by hl.exe when it’s run without parameters (see link).

    The hl.exe itself is renamed to something closer to your actual project name, feel free to rename as you wish.

    If your HXML uses the hldx library, the redistHelper will package a DirectX folder.

    If your HXML uses the hlsdl library, the redistHelper will package a OpenGL (SDL) folder.

    You can use the -hl32 to also package a 32 bits version of the HL runtimes, for older systems. Warning: this will use the last release HL 32 bits (1.10). All recent HL updates won’t be included!

    HTML5 / Javascript

    When packaging a JS target project, RedistHelper will produce a basic HTML file to load your app properly. You can use it to create your own integration.

    In your HTML body, you basically should have something like that:

    <canvas id="webgl"></canvas>
    <script type="text/javascript" src="myApp.js"></script> 

    Please note that the webgl ID is important here, as it’s the primary target for web apps build with using Haxe.

    Neko VM

    Neko is a lightweight virtual machine for Haxe which can be useful to build small command line tools for example.

    RedistHelper will turn your Neko binary file (*.n) into a Windows Executable and add all the required runtime files.

    Adobe Flash

    While Flash is supported, it’s not super useful here, as the SWF file is already a package in its own.

    Distributing on platforms

    Itch.io

    You have 2 ways to push an app on Itch.io:

    If you install it, Butler can be used right from the command line to upload your fresh new build to itch.io in a single command line:

    butler push redist/directx myUserName/my-app-name:win-directx64

    If you want to upload a JS app that should be played right from the user browser on the itch.io website, you just have to package your app using the -zip parameter:

    haxelib run redistHelper myJsGame.hxml -zip

    This will create a ZIP archive that you can easily upload to your dashboard, or send using Butler.

    Contributing

    RedistHelper is open source (under MIT license). You can download the source, adapt to your needs or add more packaging targets.

  5. Free time tracking tool

    4 Comments

    About

    This Google spreadsheet will help you to keep track of time spent on your projects:

    • Single user oriented to keep it simple,
    • Easy to add projects,
    • Shows a clear summary of your current and previous week, and how you spent your time globally,
    • this time tracker is simple and does its job,
    • you can easily have all your data at your disposal,
    • it can be updated to your needs, if you know how to do Google Sheet formulas.

    Being confined (thanks Covid19), I’ve spent some time making this tool for my own usage, to take care of my new indie career. Feel free to use, share or change it!

    How to use it?

    Make a copy of the spreadsheet on your own Google Drive (File > Make a copy)

    Go in the Projects tab, fill this sheet with your own project names & colors.

    Go in the Time Tracking tab, just enter a date (make sure to match the spreadsheet date format, see File -> Spreadsheet settings), pick a project from the list, and fill the hours column.

  6. Part 2 – Using GameBase to create an Haxe+Heaps game

    14 Comments

    Introduction

    Every time I start working a new game, I use “GameBase” as a starting point. It uses the Haxe language and the Heaps.io engine.

    GameBase offers a minimal set of classes and tools to get started quickly making your own game. It’s completely open source and easy to adapt to your needs. Oh, it’s also quite simple and not bloated with tons of useless classes or features.

    Of course, you could also start from scratch, but that’s not something I’d recommend if your goal is to learn Haxe language + Heaps engine.

    Getting GameBase

    First thing first, here is the official GameBase repository on GitHub:

    Installing Haxe + Heaps

    I wrote a step-by-step tutorial on how to install the whole thing on Windows.

    Please check it out if haven’t installed Heaps yet.

    Installing dependencies

    You’ll first need my deepnightLibs, which contain many useful classes I use in all my projects. To install it, just run:

    haxelib git deepnightLibs https://github.com/deepnight/deepnightLibs.git

    Also install CastleDB lib (a simple database for Haxe games, see castledb.org):

    haxelib git castle https://github.com/ncannasse/castle.git

    Getting the GameBase source code

    Method A: template

    Just go to the repository on GitHub and click on the Use template button. Learn more about GitHub templates here.

    Method B: fork

    Go the following GitHub repository: https://github.com/deepnight/gameBase

    Just fork this repo and clone it on your computer. Feel free to adapt/edit/copy for your own usage (see LICENSE).

    Method C: adding an upstream remote

    This method is mostly for my own usage, as GitHub doesn’t allow me to fork my own projects.

    • Make a new repo on GitHub (WARNING: do not add any license or don’t commit anything in it for now)
    • Clone it somewhere
    • on a command line:
    git remote add gameBase https://github.com/deepnight/gameBase.git
    
    git pull gameBase master
    
    git push origin master

    Checking if it works

    Compiling

    If everything is properly installed, just run the following command right from the gameBase root folder:

    haxe hl.dx.hxml

    This should generate a client.hl in your /bin folder.

    Other platforms

    You can build for other platforms:

    • DirectX for HashLink VM: haxe hl.dx.hxml (recommended)
    • Javascript (WebGL): haxe js.hxml
    • OpenGL for HashLink VM: haxe hl.sdl.hxml
    • Flash: haxe swf.hxml

    Please note other platforms could be targeted by creating a corresponding HXML file (see: https://haxe.org/manual/target-details.html).

    Running

    To run the game, execute one of these commands:

    For DirectX or OpenGL Hashlink:

    hl bin\client.hl

    For WebGL (javascript):

    start js.html

    You should see something like that:

    This is your GameBase “Hello world”

    Building and debugging from VScode (recommended)

    From VScode, just run the “Debug: start debugging” command (press F5 by default, or check the VScode command line with CTRL-SHIFT-P).

    This should run the default pre-configured HL Debug command which compiles & runs the HL DirectX version.

    If you plan to debug WebGL (Javascript) content, you’ll need one of the following extensions for VScode:

    Don’t forget to change the HXML used for code completion before starting to code:

    Check the bottom left corner of VS Code
    • Click on base.hxml
    • Change it for whatever HXML you plan to use for building/testing your game (probably hl.debug.hxml or js.debug.hxml).
    • This HXML will be used for code completion

    Making a game!

    The hero we need

    We’re now ready to make the very first any game needs: adding a playable character.

    First step: create a Hero.hx in /src/en/Hero.hx. The “en” folder is the package for “Entity”-based classes.

    This is our hero:

    package en;
    
    class Hero extends Entity {
    	public function new(x,y) {
    		super(x,y);
    
    		// Some default rendering for our character
    		var g = new h2d.Graphics(spr);
    		g.beginFill(0xff0000);
    		g.drawRect(0,0,16,16);
    	}
    }

    In the Game.hx, you can create an instance of your Hero at the end of the new() constructor.

    class Game extends Process {
    	// [...]
    
    	public function new() {
    		super(Main.ME);
    		// [...]
    
    		new en.Hero(5,5);
    	}
    

    Controller

    We now need a little bit of control. If you have a gamepad, you can use it easily. You can also still use a standard keyboard too.

    We need the dn.heaps.Controller class:

    class Hero extends Entity {
    	var ca : dn.heaps.Controller.ControllerAccess;
    
    	public function new(x,y) {
    		super(x,y);
    		// [...]
    
    		ca = Main.ME.controller.createAccess("hero"); // creates an instance of controller
    	}
    
    	override function dispose() { // call on garbage collection
    		super.dispose();
    		ca.dispose(); // release on destruction
    	}
    
    	override function update() { // the Entity main loop
    		super.update();
    
    		if( ca.leftDown() || ca.isKeyboardDown(hxd.Key.LEFT) )
    			dx -= 0.1*tmod;
    
    		if( ca.rightDown() || ca.isKeyboardDown(hxd.Key.RIGHT) )
    			dx += 0.1*tmod;
    	}
    }

    Testing

    Build & run the game (F5 with VScode) and test it. Your red hero should move left/right on key presses or gamepad.

    That’s how any great hit actually started.

    About “tmod”

    tmod is a value connected to the duration of the frame, and more precisely, the time elapsed between two consecutive game frames.

    • on 60 FPS, tmod is 1.0 (the “normal” value)
    • on 30 FPS, tmod is 2.0
    • on 120 FPS, tmod is 0.5

    tmod can be used to adjust values that are FPS dependent, such as velocities or accelerations.

    The idea is:

    • if the game runs slower (ie. less than 60 FPS), all the movement increments should be higher, to compensate for the missing frames.
    • if the game runs faster (ie. more than 60 FPS), all the movement increments should be smaller to acknowledge the extra frames.

    See Delta time to learn more about this classic concept.

    Working without “tmod”

    The dn.Process class has a fixedUpdate() which runs (or at least tries to run) at a fixed lower FPS, usually 30 or 24 FPS (check the fixedUpdateFps variable). The FPS of these fixed updates is guaranteed, within the realms of possibility.

    The Entity class also has a similar fixedUpdate() which runs at the same fixed FPS as the Game.

    A classic approach is to do every gameplay related things, like physics, or velocities inside the “fixed” updates, and do everything else (rendering, particles etc.) in “real FPS” updates.

    This keeps the gameplay code quite simple, without having to rely on the tmod/delta time values.

    You might think it would be an issue to have your gameplay code in a 30 FPS loop instead of 60 FPS or more, but bear with me: no one will notice. Dead Cells, which is known for its fast-paced action & gameplay actually uses 30 FPS loops for the gameplay elements. The render is done at 60 FPS.

    Important: all the controller related checks should happen inside the real FPS updates, because that’s the only way to catch a user input at the exact moment it happens. The fixed updates won’t catch these events, because these fixed updates don’t occur on every single frame.

    Classes & API

    Boot.hx: where everything starts

    The first thing called in your code is in the Boot.hx method main(). From here, we create a Main, which creates a Game.

    Loops

    All the updates are called in the following order:

    1. Boot.hx has an update() which takes care of low-level stuff. You shouldn’t do much here, unless you have very specific needs.
    2. Main.hx has an update() too, and is basically your global app main update. It also has a postUpdate() which happens after the update().
    3. Game.hx also has an update(), a preUpdate(), a fixedUpdate() and a postUpdate(). This is where your game related code will happen.

    Note that Boot extends hxd.App which is the top-level app class in Heaps. I use a different class for Main and Game: dn.Process.

    My dn.Process class takes care of the updates, and each Process can have children processes, support pausing, have preUpdates, fixedUpdates, postUpdates and few other useful things.

    The philosophy with GameBase is quite simple: all your future Processes should be either children of Main (any section of your app which is not the game, like an intro screen), or Game (if it’s part of the actual game).

    Important classes

    All code files are in /src folder.

    • Main.hx: the main app loop, see the update() method
    • Game.hx: created every time a game is started, it also has an update()
    • Entity.hx:: the most important thing after the Game. It’s the base class for everything that moves in the game (player, enemies, bullets, items etc.). Everything except particles (see Fx.hx). Read below for more explanations about the Entity class.
    • Level.hx: your world, level, room or whatever is your environment. Some games might have none of these, or multiple instances, it’s up to you.
    • Camera.hx: a basic camera which can optionally track an Entity (say, the player)
    • Fx.hx: a simple particle system
    • Lang.hx: a neat way to automatically extract your texts directly from your code to generate PO files compatible with the popular GetText translation ecosystem. Check the specific tutorial to see how it works.
    • Const.hx: contains a set of constant values I use to tweak my game, like the standard FPS, your starting health points or stuff like that.
    • Assets.hx: a single class to access assets like tilesets or sounds. All your assets (art, sound, other data files) that are meant to be loaded/used by the game should be put in the /res folder. You can access them in your code using the hxd.Res.myAsset API.

    Misc classes

    • import.hx: note the lowercase format of this file name, it allows to have global imports for every classes of your app (see: https://haxe.org/blog/importhx-intro/). Neat.
    • tools/CPoint.hx: a simple Point class that supports grid-based coordinates.
    • ui/Hud.hx: a process of Game which can be used for any HUD (head-up-display, aka. interface) for your game, like: gold, life, ammo etc.
    • ui/Window.hx: a simple pop-up object.
    • ui/Modal.hx: same as Window, except it pauses the game while it’s open.

    The Entity class

    Philosophy

    Entity.hx uses the same “grid-based” logic as described in my Simple 2D engine article.

    Please note that it’s totally up to you to write a very different Entity system to suit all your needs. Basically, all the 2D grid-based logic is here. Everything else in GameBase should fit any kind of game, be it a platformer, a match-3 puzzle or an hidden object.

    Features

    • Loops: preUpdate, update, fixedUpdate and postUpdate
    • Safe disposal mechanic: just call the destroy() of an Entity to mark it as destroyed. It won’t be destroyed instantly, but only at the end of the current frame (the onDispose() is then automatically called), to avoid any null value in the course of the loops.
    • Listing: access Entity.ALL static array for a dynamic list of all existing entities. Note that some might be flagged as “destroyed” (see previous point).
    • Coordinates: each entity uses a grid-based coordinate system. cx,cy are the grid coordinates, while xr,yr are the position inside a single cell. For example, cx=5 and xr=0.5 means “in column 5, at 50% of the cell“. More explanations about this approach in my Simple 2D engine article.
    • Velocities: dx,dy are the current x/y speeds of the entity (added to coordinates on each frame). They also use “grid-based” values. So having dx=0.5 means “moving 50% of a cell on each frame“. dx,dy are multiplied on each frame with frictions which slow them down (if friction<1).
    • Sprite: the visual representation of an Entity is the variable spr. It’s a dn.heaps.slib.HSprite class, which is a super-charged h2d.Bitmap. Please note that the coordinates of this sprite are only updated during the postUpdate(), it’s never updated nor manipulated outside of this loop. If you need the coordinates of the entity object, you should always refer to cx,cy + xr,yr.

  7. The Level Design of Dead Cells

    3 Comments

    This article was originally posted on Gamasutra.

    During my time at Motion Twin, I’m was the Lead Designer on Dead Cells, a procedurally generated Metroidvania.

    As you would expect, questions about the quality of our procedural generation pop up very regularly, with both players and other devs. After recent high profile procedural generation controversies, we can’t blame people for being sceptical. This is particularly obvious when talking about a genre that relies on meticulous level design at its core. So we’d like to acknowledge these concerns and take a deep dive into how we’re planning to bring rogue-lite re-playability to a metroidvania. If you’re more a video guy, we also released a “lighter” version (still rather technical (read “boring”) though) of this dev diary on youtube. 

    Before looking at the how of the matter, let’s discuss the why, the reasons we chose to involve procedural generation in a genre known for painstaking level design. 

    At first, about two years ago when we began to design and build a prototype for Dead Cells, we went for the traditional, handmade way of doing things. Unfortunately, we quickly realised that we wouldn’t have the time to do it properly, considering the modest size of our team.

    From there, we knew we had to find alternatives. Before Dead Cells, we had already done quite a lot of browser games, most of them involving randomized elements and procedural generation so we were already quite familiar with the core concepts of procedural generation. On top of this, great use of procedural generation was being shown off by a bunch of critically and commercially successful games: Isaac, Minecraft, Starbound, etc. In light of this, it seemed like an obvious choice to at least build a prototype to test out the idea for Dead Cells. 

    And it worked well, bringing more replay value, a significant improvement for a game with any type of permadeath mechanic. Even better, we found that it fundamentally altered the feeling of the combat of the game, placing the emphasis on the player’s instincts and reflexes rather than relying on rote learning a level in order to progress. Overall, it felt really good.

    There was of course a catch. While the core gameplay feeling was improved by the freshness of new enemy placement, the level design took a great big hit. In short it was illogical, chaotic and left you with no feeling of consistency or immersion in the world.

    Not satisfied with either full handcrafting or full procedural generation, we could feel that there was a way to find a middle ground that would work. 

    Here, we’d like to thank the guys behind Spelunky, who came up with some interesting solutions to the same problem. You can find a brief explanation of how that works here, if you’re interested. But to sum it up, they used a hybrid approach between procedural generation and handmade levels, giving them that consistent feeling while maintaining a lot of diversity. 

    Before we get into the technical details of how this hybrid approach is implemented in our game, I want to mention two other sources of inspiration for Dead Cells.
     
    The first one is Faster Than Light, which we regard as a model when it comes to a game allying procedural generation with a well orchestrated plot and a very consistent universe. 

    The second one is Left For Dead. Unexpected right? Well, it’s something of a trace left over from “that time Dead Cells was a zombie tower defense game” but we definitely took some lessons from their underlying ideas. In LFD, Valve designed the levels to be dynamically modified through its “AI Director” system. Have a look over here for the basic explanation of the concept, it’s really quite interesting. 

    At the time, we began to develop our own “AI Director”, adapted for Dead Cells. While there is very little of that AID in the current version, we kept the underlying philosophy: building the level’s generation system around dramatic peaks and relaxing “breaks” to ensure an interesting game pacing and keep the player enthralled.

    So to sum up, the challenge was to build a partially procedurally generated world to create a feeling of change and diversity, excellent replay value and difficulty which is based on the players reaction to an evolving situation rather than rote learning. And we had to do this while keeping a feeling of consistency between runs and levels. Learning from previous games, and after many trials, errors, adjustments and a stack of tweaking, we’ve got six steps that we hope will help you approach procedural generation with quality level design as the underpinning rule.

    1. First, we place the fixed elements, acting a bit like a frame in which the procedural generation can express itself. The overall design of the map of the island, how the different levels are interconnected, where the keys to unlock new paths for your future runs are located etc. All of this never changes no matter the loaded variant (seed) of the game. In short the overall world layout is fixed and designed by hand.

    2. Then we hand design a bunch of level “tiles” chunks of carefully designed rooms with a certain amount of variations possible in each of them depending on their configuration. Here’s some examples of the CastleDB software we use to create the tiles:

    In practice, each tile has a specific layout of platforms designed for a specific purpose. A room designed to host a hidden treasure won’t be the same as another hosting a merchant, and both will be very different from the rooms designed around combat. As mentioned there are variations possible in the handmade tiles. These are defined by a handful of parameters, mainly the numbers of entrances and exits available and the room’s purpose. 

    Each room also pertains to a specific biome: for instance rooms used in the prison aren’t reused in the sewers. This allows us to give each level its own strongly defined identity. For example the sewers are very tight, restricting the ability to jump and dodge and forcing the player to think about their mob management.

    3. Ok so we’ve got a bunch of tiles that are fun to play, now we need to arrange them in a logical, interesting way. So we create a concept graph for each level (our “biomes”). A graph is a schematic visual display of the layout of the tiles inside a biome, represented here by nodes. We start by placing the entrance and exit of the level, then we add the special rooms (treasure, merchants, etc.) and finally the tiles in between where you fight and explore. 

    This graph acts like a set of instruction to the procedural generation algorithm describing the: length of the level, number of specials tiles, how much of the biome will be a labyrinthine, how many tiles separate the entrance from the nearest exit, etc. Again, each biome has a different graph to make it consistent with the part of the island it’s supposed to represent. For instance, we made the ramparts much more straightforward and linear than the sewers. 

    4. Only once we’ve laid down all of these constraints and set out the overall level design do we let the procedural generation algorithm loose… For each node, the algorithm tries a random room, among the ones dedicated for this particular biome, and tests to see if it complies with the instructions given by the graph (location and number of entrances, type, etc). If it doesn’t match, the algorithm tries another room until it finds one. And voilà! But wait… there’s more. 

    5. Next comes the reason to keep looking around. You need something to fight. The number of monsters in one level is defined by the total length of the combat based tiles in the level. Taking some random numbers, let’s say we have 250 combat based tiles in a procedurally generated sewers level. We then define the number of monsters that should appear per combat tiles, so say for example it’s 1 monster for every 5 tiles, you’ll have 50 monsters to place in the level.

    Each type of monster has its own constraints and parameters: for instance, some monsters being more dangerous than the others will count for 10 tiles, some can’t be used more than once per tile or level, some can’t be with other monsters on the same platform, some are placed where there is a lot of space to move and fight, etc. 

    6. The final step is to generate the gold, cells and loot, but the recipe for that is kept secret. Legend has it that each dev only has access to one file controlling one loot in order to avoid abuse…

    Well, congratulations for making it through the wall of text trial! We shared our method here, in the hope that someone else will be able to get something out of our take on procedural generation. I’m also hoping to encourage others devs to take risks – like wedding two seemingly incompatible ideas. Sometimes, it might just work.  

    If you have any questions or ideas, just leave me a comment and I’ll be glad to get back to you as soon as I can.

  8. Part 1 – Installing Haxe + Heaps

    2 Comments

    For this guide, I will presume that all Haxe related files will be installed in the c:\HaxeToolkit\ directory. Make sure to update the paths if you install your files somewhere else!

    Haxe

    Installing

    Haxe is a cool programming language that can compile to multiple platforms. It’s free and open-source.

    Install it (including Neko) to a folder like: c:\HaxeToolkit

    Important: for the next sections of this tutorial, I’ll assume Haxe is installed in this folder.

    After the setup, you should get 2 folders:

    • c:\HaxeToolkit\haxe: the compiler and all the standard libraries
    • c:\HaxeToolkit\neko: the Neko VM which is used internally.

    Does it work?

    • Open a command line,
    • Type haxe, you should see something like that:

    If you get a “file not found” error:

    1. reboot,
    2. check again,
    3. if it still doesn’t work, re-install.

    Hashlink

    Installing

    Hashlink (HL) is Haxe virtual machine. We use it to build cross-platform titles.

    Install it to the Haxe toolkit folder: c:\HaxeToolkit\hl

    Important: you must add all the Hashlink (hl.exe) folder to your PATH environment variable (how?).

    Does it work?

    From a command line, type hl:

    If it doesn’t work:

    1. reboot,
    2. check again,
    3. if you get an error, type where hl,
    4. if you get an unknown command error, check your PATH environment variable.

    Installing Heaps

    HeapsIO is a free open-source 2D/3D engine used in large game projects, like Dead Cells, Northgard or Evoland 2.

    The engine is actually a library of Haxe (ie. an Haxelib) which can be installed easily using the bundled haxelib.exe tool.

    From a command line, run the following command:

    haxelib git heaps https://github.com/HeapsIO/heaps.git 

    Important: we won’t use the default haxelib install heaps command here, because the official GIT version is much more up-to-date than the haxelib repo.

    Installing other important Haxe libs

    From a command line, for DirectX support in HashLink:

    haxelib install hldx

    For OpenGL/SDL support in HashLink:

    haxelib install hlsdl

    You can check the installed libs by typing:

    haxelib list

    Working with VSCode (recommended)

    VScode is a nice IDE that features full Haxe integration if you install the dedicated extension. Out of the box, you’ll get code completion, easier project setup, debugging & much more.

    Please note that you can do that from the extension panel. See below:

    Use the built-in extension browser to get latest Haxe Extension Pack

    Making a game

    Now everything is ready, we can take care of the most interesting part: making an actual game using my GameBase.

  9. Going rogue!

    19 Comments

    TLDR version:

    I left Motion Twin, the game company I worked at for about 18 yrs.

    I’m now becoming a full-time indie game dev, and it feels really great! :)

    Read the announcement on Twitter

    A little bit of history: the F2P era at Motion Twin

    Different Motion Twin logos from the last 18 years

    I started working at Motion Twin in 2001: I was hired as a graphic artist to update the art of existing games. But being a coder first, my art wasn’t that great (sic), so I quickly switched back to development, and we hired an actual 2D artist.

    The company was new: we barely existed for only a few months. So we spent a few years trying things, without great success, until we met the CEO of Prizee.com, a quite notorious French website specializing on virtual scratchcards.

    Long story short, we discovered the free-to-play (F2P) model with them, and kind-of imported it in France. Prizee and this new business model helped us in gaining a financial independence: for the first time, we were earning our living from making games, and were paid by players instead of publishers or pro clients.

    We spent the next ~10 years creating tons of web games, from simple match-3 titles (Swapou), or pokemon-like titles (DinoRPG) to more hardcore things like Hordes, Intrusion or Alphabounce DSi.

    But the web as we knew it was about to collapse with the arrival of the first iPhone.

    We tried to make a few mobile games (Uppercup Football, Monster Hotel) but we quickly realized that creating F2P games on mobile was waaaay different from making F2P for the web.

    Hey, please note I don’t want to sound like the old guy bragging about how better the good’ol times were, but… Seriously, web F2P was pretty much all about gameplay & making an actual good game, mostly because you had some level of control on traffic sources & user acquisition. Mobile F2P on the other hand was (and still is) all about data: ARPU, user-optimizations, funnels, retention, and basically, any stupid idea to make players pay on a daily basis. If you know what a “daily quest” is, you certainly know what I’m talking about.

    Damn, I think I sounded like an old guy bragging.

    Dead Cells

    I already talked a little bit about the story behind the game before, so let’s just say that this project was a real game-changer for Motion Twin and saved our asses from the F2P shift.

    I was the lead on this project, and honestly by this time, I couldn’t have imagined what the success of this game would be.

    For us, making a PC game wasn’t the easiest way to leave the web market. The name “Motion Twin” didn’t mean anything to people outside of France, and Dead Cells was our very first Steam title.

    Furthermore, the early access thing was a really intimidating experience for us. You know, it was Indiepocalypse everywhere, and Steam was over-crowded and dying, according to everyone. So, going all-in on this platform sounded like a very risky move to many people. Including us. The company was in a very bad shape, and failure would have probably let to destruction.

    At first, our sales expectations were around something like ~20k units during the first few months. We actually sold ~100k units on the first week. As of today, the game sold more than 2.5M units across all platforms. These results were absolutely crazy…

    To me, working on Dead Cells was probably the best time I ever had at Motion Twin: we were a dream team, players loved the game and Dead Cells was trusting the top charts.

    Dealing with the early access

    This success put higher expectations on us. We wanted to deliver the best possible game: that meant giving everything to it.

    This update was called The Brutal one for good reasons: it was probably one of the most ambitious change of Dead Cells.

    To meet these expectations, we planned monthly major updates during the early access, which meant “make big changes but don’t change things too much”, from a marketing perspective. So to me, everyday was a delicate balance between fixing the gameplay, following the vision and listening to the community.

    And boy, that was a complicated task!

    We didn’t crunch a lot, though ; maybe a few weekends by the end of the early access, but that was it. But I was basically thinking about Dead Cells all the time. During work hours, evenings, weekends and holidays. Every time I wanted to make a major gameplay change, I knew that the other devs would be waiting for me. So I kept myself under-pressure to deliver a good game while sticking to the deadline. That was pretty intense for everyone. Maybe too much.

    “Next project 2019”

    After the release of Dead Cells in 2018, we kept working on a few big free DLCs and updates for about 1 year. We then decided to give the baby to a (kind of) new company, Evil Empire, created by a former Motion Twin member, Steve Filby. You can read the announcement on Steam.

    We then decided to switch the main team (aka. Motion Twin) to a “Next Project” research phase. The broad idea was to create multiple small prototypes, in game jam way, to find an unifying idea. Things didn’t go as expected: designing all together a new large project from scratch proved to be a huge challenge.

    The unique cooperative approach of Motion Twin is, in my opinion, the perfect tool to make people work together in a human centred environment and raise the overall final product quality. But it was clearly not the best tool when all we needed was to define a robust creative vision that would serve as a base for a large project.

    Actually, before Dead Cells, all our previous games were actually small projects initiated by 1 or 2 people in the team, that grew larger as they left pre-production phases. Even Dead Cells started like that: I created the core concepts, Thomas Vasseur was experimenting with the art & rendering, and we basically started this roguevania as team of 2. Then the rest of the team started to join, driven by production needs.

    After Dead Cells, the team wanted to create the next game all together: we wanted to try to have a global vision by making 8 people getting in tune with each others. Seemed like a complicated task, if you asked me back then, and, damn. It was.

    During this “Next Project” period, I built about a dozen prototypes (game design, code & animations, while the background art was mostly bough from Itch.io), but none was validated to turn into an actual Motion Twin game. Of course, I wasn’t the only one to create prototypes, but nothing was promoted to an actual global project.

    As months passed by, and nothing happened, my relations with the team became more and more complicated. So complicated, actually, that it ultimately led to my forced departure, as I was asked to leave in December 2019.

    Background art credits: Cavernas by Adam Saltsman, Inca by Kronbits, 8BIT top down by Canari Games, Gwenaël Massé.

    What now?

    Trying to create the post-“Dead Cells” game was a very stressful task, and it now feels incredibly great to be able to think about smaller scope projects. “Smaller” doesn’t mean I plan to work on very small experimental games though: I still want to release complete titles and I still plan to sell them on Steam, or other markets ;)

    Right now, I’m eager to start working on 2 game projects I’ve been thinking about a lot. I also plan to update RPG Map, including a possible Steam release, if it’s accepted on the store. And of course, I have Ludum Dare and other game jams :)

    I also updated the games page to list all projects I’ve worked on at Motion Twin and, before that, on Atari ST. It was a very interesting introspective thing to do: good to look where you’ve been, to decide where you’ll go next.

    Last but not least, I want to come back to things I left years go: taking active part in open communities. Being a Haxe developer, my first focus will probably be the game dev community gathering around this language, by helping newcomers getting onboard.

    I honestly feel great today. The success of Dead Cells gave me some legitimacy which will certainly be useful in the near future and I’m super excited to start working on personal stuff.

    So, expect new things in the next few months, I’ll keep you updated on my Twitter :)

  10. "Game feel" demo

    6 Comments

    This prototype is not exactly an actual game. It was developed to serve as a demonstration for a “Game feel” talk in 2019 at the ENJMIN school.

    It shows the impact of small details on the overall quality of a game.

    You will need a GAMEPAD to test it. You can enable or disable game features in this demo by pressing the START button.

  11. Sabotage

    14 Comments

    POST-COMPO VERSION

    This is the post-compo version of my Ludum Dare 45 game: Sabotage.

    Changes include:

    • better controls
    • HUD
    • auto-pick some items (keys & healing)
    • balancing

    ABOUT

    You are Colonel Jean-François Hubert from the French army. As the most badass colonel ever, you take on your missions naked, without any weapon.

    Improvise, adapt, overcome.

    Sabotage is my Ludum Dare 45 entry. It was created in about 72h using Haxe language. The theme was “Start with nothing”.

    CREDITS

    Music by David Whittaker, from the game Leatherneck (Atari ST version)

    HOW TO PLAY

    You start with absolutely nothing: use the environment to kill enemies. 

    Play using keyboard or a compatible game pad (Xbox controller recommended).

    Keyboard

    • ARROWS – move around
    • SPACE – grab/use an item
    • ESCAPE – release current item
    • R – restart current level

    Gamepad (xbox controller)

    • LEFT STICK – move around
    • A – grab/use an item
    • B – release item
    • SELECT – restart current level
  12. Sabotage (72h version)

    4 Comments

    ABOUT

    You are Colonel Jean-François Hubert from the French army. As the most badass colonel ever, you take on your missions naked, without any weapon.

    Improvise, adapt, overcome.

    Sabotage is my Ludum Dare 45 entry. It was created in about 72h using Haxe language. The theme was “Start with nothing”.

    CREDITS

    Music by David Whittaker, from the game Leatherneck (Atari ST version)

    HOW TO PLAY

    You start with absolutely nothing: use the environment to kill enemies. 

    Play using keyboard or a compatible game pad (Xbox controller recommended).

    Keyboard

    • ARROWS – move around
    • F – grab an enemy or an item
    • SPACE – punch (if your hands are free)
    • SPACE – use item in your hands
    • R – restart current level

    Gamepad (xbox controller)

    • LEFT STICK – move around
    • A – grab an enemy or an item
    • X – punch (if your hands are free)
    • X – use item in your hands
    • SELECT – restart current level
  13. Save & Sacrifice

    7 Comments

    About

    You are the Supreme Lord Commander of the Heavens, which is kind of cool.

    Hell is on Earth, and you were sent down there to save your fellow worshipers. Well, actually, your contract says you should at least save ONE worshiper in each area.

    The other might be sacrificed for the greater good.

    HOW TO PLAY

    Play using keyboard or a compatible gamepad (xbox controller recommended).

    Keyboard

    • ARROWS – move around
    • UP – jump / use wings
    • SPACE – kick
    • R – restart current level

    Gamepad (xbox controller)

    • LEFT STICK – move around
    • A – jump / use wings
    • X – kick
    • SELECT – restart current level
  14. Dead Cells

    1 Comment

    I created Dead Cells, as lead game designer and lead developer.

    The concept is born from the ashes of Hordes Zero, a multiplayer tower defense game for web & mobile, featuring coopetition (play together, but only the last survivor gets a reward). This early project even had a public Alpha version, but it proved to be a really big failure: not fun, no clear vision and tons of gameplay & balance issues.

    An ingame screenshot of the last “tower defense” version of the game, before it was sliced down to a single player Castlevaniesque adventure.

    We basically decided to cut every single aspect of the project that we were not confident with: mobile, cross-platform, multiplayer and last but not least, tower-defense.

    This was a “last chance” move to save the project (and the company, we were not in a great shape) from obliteration. It was also the moment we decided to go “all-in” on Steam & PC, which was something completely new for us.

    The final product is quite different from the original idea as you can see ;) We decided to call it a Roguevania, because it sounded cool, it was quite close to the actual game concept and because no one could stop us from doing stupid things.

    One would say this change from Tower Defense to Roguevania was a good move, as the final game sold more than 2.5M units on all platforms and even won the Best Action Game award, during the Game Awards in 2018.

    A very early mockup of the game, when it was still a top-down tower defense in a modern world.

    Final game screenshots

    In-between prototype

    Tower defense prototype

    Early prototypes

  15. Blossom

    2 Comments

    If everything is lost, try to plant a seed.

    This is my Ludum Dare 42 entry! You are a tree. Try to escape pollution by growing away, planting seed and picking magic stars that will clean up some dirt.

    Please note that I made it in about 9h, and partially during a flight between Taipei and Paris. So don’t expect much here:

    • no sound,
    • no music,
    • no proper ending :)
  16. Nightclub Showdown

    14 Comments

    Don’t aim. Shoot quickly. Then go for the head and finish the job.

    — John Wick

    This is the post-compo version my Ludum Dare 41 entry! It features :

    • the ability for you to grab enemies to use them as cover!
    • a new enemy type (strong big guy),
    • a better UI,
    • updated music & sfx,
    • an extra combat area,
    • balancing.

    If you intended to vote for Ludum Dare 41, please rate the original jam version.

  17. Nightclub Showdown (original 24h version)

    2 Comments

    Don’t aim. Shoot quickly. Then go for the head and finish the job.

                                                           — John Wick

    This is my Ludum Dare 41 entry!

    My goal here was to try mix turn based and fast action. I drew a lots of inspiration from John Wick movie & gun fights :) This game is quite special to me as I only created it in less than 24h! Much happy.

  18. Cats are assholes

    24 Comments

    Praise the cats, hooman.

    A shelter simulation game made in 3 days for Ludum Dare 40. Even if the game was submitted to Jam instead of Compo, I still made everything all by myself.

    All you have to do is to take great care of your beloved stray cats. If you fail, they will eat you, plain and simple. Make sure the fridge and the bowls are always full of fish, empty the litter boxes, buy extra equipment and upgrade your existing fridge capacity.

    Be sure to use Mark, your grandson, as often as possible! That’s basically how you do multi-tasking in this house.

  19. Zero Volt X

    12 Comments

    Manage your ship power distribution while avoiding thousands of bullets!

    A 48h shooter I made for Ludum Dare 39 gamejam! The theme was “Running out of power”. Once again, this game is actually the second one I made during a single gamejam weekend. I cancelled the first one because it wasn’t fun at all, so I decided to switch to a shooter with a fast paced gameplay like old-school ones :)

    How to play

    Distribute your generator power to your ship sub-systems. Max out the Shield to regen it when you get hit, max out Gun to increase damage in front of you and max out Missiles to throw dozens of homing missiles around you!

  20. Lost in pandation (jam version)

    Leave a Comment

    A survival game with an iPanda, lots of snow, horrible creatures and a cable car.

    Tips:

    • your objectives: produce Oily Fruits to fill the Generator in the upper right corner, use the machine in the upper left corner to build Batteries, use Batteries in the slot on the right to escape :)
    • plant everything and maintain a good production at any given time
    • unlock the extra Pot as soon as possible
    • kill all enemies using the button above the Fire camp if submerged by them

    Music by Volkor X!

    Official LD page | Play original compo version | Download (Windows)

  21. Lost in pandation

    33 Comments

    A survival game with an iPanda, lots of snow, horrible creatures and a cable car.

    Created in about 48h for the Ludum Dare 37 ; the theme was “One Room”.

    Tips:

    • your objectives: produce Oily Fruits to fill the Generator in the upper right corner, use the machine in the upper left corner to build Batteries, use Batteries in the slot on the right to escape :)
    • plant everything and maintain a good production at any given time
    • unlock the extra Pot as soon as possible
    • kill all enemies using the button above the Fire camp if submerged by them

    Music by Volkor X!

  22. Sub Dragon

    47 Comments

    Sub Dragon is a shooter inspired by Saint Dragon on Atari ST. Your ship has 2 sides: the white one (left) is invulnerable and can stop enemy bullets. The red one is heavily armed but very fragile!

    Move around like a snake, change shape and use both sides wisely to eradicate every opponents!

    This game was made in 48h for the Ludum Dare 35. The theme was “Shapeshift”.

  23. Monster Hotel

    Leave a Comment

    This game is a sequel to CroqueMotel and was specifically designed to be a “safe” first title for the mobile market, as Motion Twin was transitioning from the browser-based market.

    To me, it was a reality check for what making a free-to-play on mobile was really all about. Nightmare.

    We’ve spent most of our development working on “mandatory” social features such as daily quests, sharing mechanics, ARPU optimizations (Average Revenue Per User) and other dumb stuff.

    The remaining time was split between actual gameplay coding and UI/UX (interface), the second being actually quite interesting.

    The game wasn’t a hit, nor a big failure. It had potential, which means, in “mobile game industry standards”, a good reason to be iterated for months until you get the right ARPU.

    So we decided to rage quit all this shit. It was a huge turning point for Motion Twin: the company was in a very bad shape, as we knew that we would probably be in the red zone the following year. Basically, we were running out of money.

    We decided to give up the mobile platform & the browser-based gaming to try to make our first PC/Steam title: Dead Cells.

  24. Delicious Cortex

    51 Comments

    You are the Lich King. The annoying City Watch is messing around your domain so you take the only decision that fits such a situation: you invoke minions to kill everyone :)

    In Delicious Cortex, you don’t control your minions directly. You just lead them around and try to give them orders. But hey, they’re zombies, so don’t expect to much.

    Official LD page | Timelapse

  25. Badass Inc (extended)

    1 Comment

    This version is born from the Ludum Dare jam version I created.

    We wanted to make some kind of proof-of-concept for a longer version of this title, developed by a full team.

    The result was really cool, but by the time we wanted to make it, we were also working on Dead Cells, and both titles were our very first PC/Steam titles. As we were a small team of 8 people, it was obvious that making both games wasn’t such a great idea. We needed to learn everything about Steam development & marketing and couldn’t afford to split our efforts on 2 very different kind of games.

    In the end, we gave all our hopes to Dead Cells (later proved to be a great idea, as it saved Motion Twin from destruction).

    The soundtrack was created by VolkorX, and totally transformed the game from a vague prototype to something with great mood. It is available on BandCamp for a super cheap price:

    Get BadassInc OST on BandCamp
  26. Badass Inc (48h version)

    Leave a Comment

    You are a (really badass) contract killer on her latest mission. You usually prefers a very direct approach. “Head-on, gun loaded, never give the target the time to realize what the hell is happening”, is her motto. But this time, her clients want her to kill the contract in a non-conventional way. Something original. So she decides to lock the victim up inside his own apartment and leave him to die from starvation.

    Badass Inc is my tribute to Blade Runner, Another World & Flashback. It’s pretty short but packed with lots of love :)

    Official LD page | Play the extended version | Source code | Timelapse | Read the post-mortem (blog)

  27. Badass Inc. post-mortem

    8 Comments
    08

    Badass Inc is my Ludum Dare 32 entry ; the theme was An unconventional weapon. There is usually 2 ways to deal with the theme: gameplay wise or through story telling. I opted for the second direction for this entry.

    You play a (badass) contract killer on her latest mission. She usually prefers a very direct approach. “Head-on, gun loaded, never give the target the time to realize what the hell is happening”, is her motto. But this time, her clients want her to kill the contract in a non-conventional way. Something original. So she decides to lock the victim up inside his own apartment and leave him to die from starvation.

    Badass Inc was mostly inspired by various video games:

    The art

    10

    For a really long time, I wanted to spend more time on the art during Ludum Dare. Usually I only create minimal spritesheets for my games and compensate with loads of particle effects & 2D filters to glue everything together. On Badass Inc, I spent more than 4h on the main character, creating a decent walk animation & charadesign. The backgrounds occupied quite a huge time too, and working on them was a bit intimidating at first (so many things to do, so few time!)

    I took my inspiration from Deus Ex (did you recognize the golden spheres?), Future Wars and the Last Night.

    The animation

    I can really confess I’m super proud about the animations of my main character :) It took me 4h, but the result and the general feeling is really satisfying! I would never have tried such a risky character animation if I hadn’t experimented it a little bit on one of my previous game: Strike of Rage.

    The only problem here was the process: I designed the character, and only then, I created the walk animation. It really took me lots of time to adjust the animation because of all the details of the body. And when I had to create a second animated character, I couldn’t easily use the previous work as a base for its own walk animation.

    A much better process would have been to create a “skeleton” of the walk animation, tune it, then, and only then, skin it. I could have reused this skeleton for the second (or third) character. Sounds like an evidence, after wise, captain obvious. Next time, I’ll definitely do it better.

    The sound design

    07

    I really didn’t have time to create the music I wanted for this game: one extra hour would have been great. Fortunately, Bosca Ceoil, from Terry Cavanagh, is really a great tool when it’s about creating a music quickly. The result was a bit repetitive to me and I had to greatly turn the sound down to make it fit in-game.

    The same goes for the sound fx: I quickly generated a few bleeps, pew-pews and bangs using LabChirp, and that was it.

    The story

    09

    Just like the sound design, I didn’t have much time to implement a decent amount of content in the game. The result is a really short story and quite simplistic puzzles. It would be easy to fix this up, but given the 48h limit, I had to make choices and many story-elements were simply cut off.

    One idea that didn’t make it into the game was a a more open puzzle gameplay where you could actually choose your “unconventional” way to kill your target (like using a soap to make him fall from its balcony etc.).

    Anyway, if you still haven’t, please try Badass Inc and leave a comment below if you have any question :)