Space Invaders meet ConfigCat and MelonJS
Tags: configcat, javascript, spaceinvaders, melonjs
Published: 2022-02-21 19:03:25


Growing up as a child of the ’90s has always been a bitter-sweet kind of experience, but it certainly also came with a multitude of benefits. We’ve been exposed to countless priceless moments that have come and passed, moments that stand to make history and which may never be experienced again by newer generations. One such example of a beautiful lived-through historical moment is growing up with the fabled **Space Invaders** game.
 Simple yet memorable, Space Invaders made waves across the world and undoubtedly served as a catalyst for the revival of a previously stale and dying gaming industry that’s now priced at no less than 173.7 billion USD.

## What we're going to do
Nostalgia trip aside, the plan here is to rebuild “Space Invaders” in MelonJS while also taking advantage of ConfigCat's **[feature flag management service](https://configcat.com/)** to toggle your player's ship from the default one to another, more custom version. 


## What is MelonJS​ ?

![MelonJs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xu6tkqt3f7qmtq0egi9.png)
Well, silly naming scheme aside (which may or may not give you a craving for melons), it’s an:
- actively maintained
- open-source
- JS-powered game engine that’s licensed under MIT

**Personally, I’d go for MelonJS 2**, as it’s a modern remake of the engine that's perfectly adapted to support ES6 class, inheritance, as well as many other goodies. If you want to learn more about what it can do, check out their docs right [here](https://melonjs.github.io/melonJS/docs/). 

## What are Feature Flags? <img align="right" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d46a8742tulrty3p9yw7.png"> 
In short, you can visualize a feature flag as a switch that’s used to activate or deactivate certain functionalities that may be present in your application. 

#### Here are some examples of why you may want to use feature flags:
- give early access to new features to only a select few
- targeting specific demographics
- various other testing purposes
- releasing things in a more ordered and stable manner

## Why use ConfigCat? ![cat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6tw5olfyidvst8ongn5.png)

What makes ConfigCat attractive is that they offer a very balanced **[forever-free plan](https://configcat.com/#pricing)**, which includes a plethora of things, including **their entire security stack** (while most other competitors would have you pay extra for those). This eliminates any artificial incentive for you to upgrade unless your business organically scales to new requirements.

You could technically create your own in-house feature flag service, but it would make more financial sense to just use an already existent one like [ConfigCat’s](https://configcat.com/#pricing). 

## Time to build Space Invaders!

![spaceInvaders](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3t4gvzmdm8gh6ld0g5dv.png)
The version of Space Invaders that we’ll be building won’t be anything truly fancy, just your average, stripped-down base game with no extra bells and whistles. We’ll have a set of ships arranged in an 8 by 4 grid rushing toward our ship. 

### Project structure
The easiest way to start your project is by getting the **[ES6 boilerplate](https://github.com/melonjs/es6-boilerplate/archive/refs/heads/main.zip)** provided by MelonJS. After that just trim your excess folders and files, and the result should look like this:

````
src
└── data
|    ├── img
└── js
|    ├── renderables
|    └── stage
├── index.js
├── index.css
├── index.html
├── manifest.js
````
Here's the **[repo link](https://github.com/ManuelPopa/melonJS_invaders_game)** of the finished game, in case you want to follow along. 

### Building the game
To start using MelonJS, we’ll just add the following line to the top of each file where we’ll need to use its functionalities:

````
import * as me from 'melonjs/dist/melonjs.module.js';
````

For this project, we’ll add three more files under the js folder: 

- **constants.js** - used to define things like laser’s width and height
- **laser.js** - used to define the Laser entity
- **enemy-manager.js** - used to manage the creation and movement of the enemy ships

The entry point for your project is the **index.js** file where the canvas is prepared and all the prerequisites for the game are preloaded by the ``onReady()`` method:

````
me.device.onReady(() => {
    setTimeout(() => {
        if (!me.video.init(
                1218, 562,
                {parent: 'screen', scale: 'auto', scaleMethod: 'flex-width'})) {
            alert('Your browser does not support HTML5 canvas.');
            return;
        };
        me.audio.init('mp3,ogg');
        me.loader.crossOrigin = 'anonymous';
        me.loader.preload(DataManifest, function() {
            me.state.set(me.state.PLAY, new PlayScreen());

            me.pool.register('player', PlayerEntity);
            me.pool.register('ships', EnemyEntity);
            me.pool.register('laser', Laser);

            me.state.change(me.state.PLAY);
        });
    }, 5000);
});
````
Under the renderables folder we have two files important for the movement and interactions of the ships soon to be battling each other:

- **enemy.js** - used to define EnemyEntity
- **player.js** - used to define PlayerEntity

The epic battle will be staged in the stage folder, inside the **play.js** file where we have the ``onResetEvent()``, ``onDestroyEvent()`` and ``checkIfLoss()`` methods which will dictate the way our game will work.

All the images we’ll need can be found in the **"data/img folder"** and we’ll use them in the **manifest.js** file as such:

````
const DataManifest = [
    {name: 'player', type: 'image', src: 'data/img/player.png'},
    {name: 'player2', type: 'image', src: 'data/img/player2.png'},
    {name: 'ships', type: 'image', src: 'data/img/ships.png'},
    {name: 'bg', type: 'image', src: 'data/img/bg.jpg'}
];

export default DataManifest;
````

### Tips and Tricks

- If you want to add a custom background picture to the game, use the following code to the ``OnResetEvent()`` method, located in the **play.js** file: 

````
 me.game.world.addChild(new me.ImageLayer(0, 0, {
	image: "bg", 
	repeat: "repeat",
	z: 0
 }), 0);
````

- One issue that you may encounter is with the game’s resetting functionality when calling the ``checkIfLoss()`` function. The bug seems to be caused by the ``bounds.bottom`` argument which may sometimes equal infinity. You can easily go around this bug by just adding the following check at the end of the first if statement in the **enemy-manager.js** file - at the time of writing, this was at line 40.

````
if (me.state.current() instanceof PlayScreen) {
me.state.current().checkIfLoss(bounds.bottom);
};
````

In the end, if all goes well and the Gods of coding are merciful, you should be able to see this: 

![gif1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjx3c0fquxzwqvash564.gif)



### Using ConfigCat's Feature Flags in Space Invaders

Let's say that I want to change the main ship with a custom version to be displayed to a specific audience. The easiest way to do this without having to change the code and make another deployment of the new version is to implement a feature flag, which can be switched on and off with ease. 

I intend to show the custom version of the ship only if the evaluation of the flag is true. And since the application is written in Javascript, I’ll choose **[ConfigCat's Javascript SDK](https://configcat.com/docs/sdk-reference/js)**, for which the process of installing is fairly straightforward and well **[documented](https://configcat.com/docs/)**.

Just fire up **npm** and run ````npm install configcat-js````, after which just import it in **constants.js** file via the following line:

````
 import * as configcat from "configcat-js";
````

The next thing that you need to do is to quickly head over to ConfigCat’s registration page and [create a free account](https://app.configcat.com/) for yourself. After which you’re all set to create your first feature flag. I named mine **"isMyFirstFeatureEnabled"**. 

![feature flag](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5u3n6bfj6dhu3ajg6uge.png)


I'm now free to go to **constants.js** and add my SDK key (which you can grab from the [ConfigCat Dashboard](https://app.configcat.com/) where you created the flag earlier). Once in the dashboard, you'll see a button in the upper right-hand corner called “View SDK Key”.

**I then create the client like this:**

````
  let flag ;
  const client = configcat.createClient(sdkKey);
  const getFlag = () => flag;
  client.getValue("isMyFirstFeatureEnabled", false, value => {
     flag=value;
  });
````

Now that the client is in order, we should now hop in the **player.js** file, import the ``getFlag()`` method from **constants.js** and use it to load the player with a new ship depending on the flag’s value: 

````
  if (getFlag()) {
	image = me.loader.getImage("player2");  
  } else {
	image = me.loader.getImage("player"); 
  }
````

Last but certainly not least, all that’s left to do now is to use the [ConfigCat Dashboard](https://app.configcat.com/), flip the flag to "true" and then reload the game. 

**BAM! The result should be something like this:**

![gif2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xz3g4m0v3lisv4erboco.gif)



## Conclusion​

**MelonJS is a powerful JS game engine** and as a testimony to this stands the vast [documentation](https://melonjs.github.io/melonJS/docs/) that you need to read in order to unleash its true power. It certainly can help you in case you want to have a chance at making the next big game hit. **Feature Flags can be outstandingly scalable and useful**, and I’m glad that I found **[ConfigCat](https://configcat.com/)** to help me out with this. 

Here’s the **[git repo link](https://github.com/ManuelPopa/melonJS_invaders_game)** in case you want to check out this tiny Space Invaders remake and I hope you that you'll get to relive some nice childhood memories playing it. 

If you are looking for more articles like this, make sure to check out [ConfigCat’s blog posts](https://configcat.com/blog/) or you could follow them on your [Facebook](https://www.facebook.com/configcat), [Twitter](https://twitter.com/ConfigCat) or [LinkedIn](https://www.linkedin.com/company/configcat/) accounts.