Hello Instant Games X (IGX) SDK

Welcome to the web wrapper to wrap them all!

IGX SDK

IGX SDK


Hey fellow game developers. I’ve spent the best part of this last year researching, analysing and developing games for the Facebook Instant Games platform. Whilst it has been incredibly fun it has not been profitable, in fact I have lost a lot of money. Even so I still have faith in the platform and I do believe that one day it will come through for indie game developers trying to break through.

With this in mind, I’ve spent the best part of the last month working on something interesting and useful that I hope Facebook Instant Game (IG) developers and web developers alike find useful, hopefully encouraging more game and entertainment app developers to come to the platform, as well as give existing developers another way to monetise their instant games elsewhere.

Now I’ve explained the inspiration behind the creation, I will explain a little more about it.

I have created an open source layer called IGX. This is an SDK that has multiple purposes:

  • Bridges the gap between Facebook Instant Games and the web, allowing Facebook Instant Game developers to deploy their games to web and monetise them with little to no changes
  • Enables web game developers to include support for Facebook Instant Games before deploying to the platform
  • Enables all developers to use a common API which allows them to deploy their games across many web portals and provides common game services
  • Extend the IG platform, providing new features via other services

What is IGX? It is basically a complete replacement for the FBInstant object, so you can drop it into your code instead of linking to the FBInstant SDK CDN and your game should just run outside of the IG platform. IGX is based very heavily on two concepts, services and vendors. A service is a feature such as login, payments, ads etc, whilst a vendor is the provider of a particular service. For example, PayPal is a purchasing vendor. Note that some vendors provide many services, for example Xtralife provides user management, leaderboards, back-end storage etc..

You have some minimal setup to carry out depending upon which services and vendors you use, but once set up your game will deploy to that specific platform using all of its features.

Note that not all features of the Facebook Instant Games API are supported but most are. Take a look at the Github repo for more details. Also don’t forget to check out the Wiki.

Note that IGX is still very heavily in development so new services will be added over time. If you find a service that you would like adding then please get in touch with the details.

A new version of Booty5 the free HTML5 game editor will be released in due course with full support for IGX and easy deployment.

Join the IGX SDK community on Facebook.

Facebook Instant Games Category Analysis September 2018

I did an analysis of Facebook Instant Games categories nearly two months ago, lets take a look at the numbers to see where we are at today.

  • Action – 666 games (44780600 total MAU – average per game is 67238)
  • Puzzle – 1146 games (43072900 total MAU – average per game is 37585)
  • Sports – 310 games (42281800 total MAU – average per game is 136392)
  • Trivia & Word – 138 games (31242800 total MAU – average per game is 226397)
  • Simulation – 166 games (28493800 total MAU – average per game is 171649)
  • Board – 126 games (19552200 total MAU – average per game is 155176)
  • Runner – 299 games (14987000 total MAU – average per game is 50123)
  • Card – 76 games (9598200 total MAU – average per game is 126292)
  • Match 3 – 117 games (5194400 total MAU – average per game is 44396)
  • Role Playing – 86 games (5026800 total MAU – average per game is 58451)
  • Strategy – 78 games (4690700 total MAU – average per game is 60137)
  • MOBA – 5 games (2255000 total MAU – average per game is 451000)
  • Poker & Table – 35 games (1705500 total MAU – average per game is 48728)
  • Slots – 35 games (1367700 total MAU – average per game is 39077)
  • Bingo – 10 games (1268900 total MAU – average per game is 126890)
  • Card Battle – 7 games (682900 total MAU – average per game is 97557)
  • Builders – 16 games (631300 total MAU – average per game is 39456)

Last time Word and Trivia had a clear lead, but things appeared to have changed somewhat over the past few months with MOBA pushing way ahead. But, looks can be deceiving. There is only one game in that category which is called Tanks Battle and it is pulling the category average way higher than it should be. The other games in the MOBA category are doing incredibly badly. That said, it does show that there is room there for a good MOBA (hint hint).

So we are still left with Trivia and Word games leading which is astonishing considering most of these games are English language only.

Booty5 HTML5 Game Maker Update – Support for Facebook Instant Games Added

Facebook Instant Games Support

Finally released the latest version of Booty with support for Facebook Instant Games. Within the Booty5 engine you will find a new class called Instants which is a small wrapper around the Facebook Instants SDK. Games exported from Booty with Instants enabled in the settings will automatically initialise the Facebook Instants SDK and download all preloaded global resources, note that you will need to download any scene local resources yourself after the main download.

To make your project Facebook IG compatible simply tick the Facebook Instants check box in the projects settings then enter the local launch URL into the Host box in project settings, e.g:

https://www.facebook.com/embed/instantgames//player?game_url=https://localhost:8080/

Dragon Bones Animation Support

Unfortunately you cannot edit Dragon Bones animations within the Booty5 editor but you can add the associated PNG, skeleton and atlas JSON files that are exported from Dragon Bones to the editor as resources and access them from within code, e.g:

// Parse dragon bone data
var factory = dragonBones.b5Factory.factory;
var skel = JSON.parse(b5.Utils.resolveResource("my_skeleton", "raw").data);
var atlas = JSON.parse(b5.Utils.resolveResource("my_atlas", "raw").data);
factory.parseDragonBonesData(skel);
factory.parseTextureAtlasData(atlas, b5.Utils.resolveResource("my_texture", "brush"));

// Create an actor containing the dragon bones armature and attach it to a parent actor
var dba = factory.buildArmatureDisplay("name");
dba.animation.play("anim");
dba.x = 0.0;
dba.y = 0.0;
ParentActor.addActor(dba);

I will in the near future wrap the above into the engine / editor to make it more readily accessible, as well as add the same support for Spine.

Other Stuff

The editor has had a whole host of bug fixes and additional changes to keep pace with the Booty5 game engine. See the Booty5 game engine for more details on those changes.

Upcoming Demos and Documentation

Over the next few days I will be releasing the full Booty5 projects for some of my recent Facebook Instant games so you can use these as a reference / starting point. These games cover many areas of the Facebook Instants SDK including displaying ads, using in-app purchases, submitting leaderboard scores, grabbing and displaying leaderboard entries, inviting other players to play, sharing progress, switching contexts and posting updates to Messenger.

The following full projects have been uploaded thus far:

You can grab the latest version of the Booty5 Game Maker from the Booty5 website.

I am still in the process of updating documentation, I will post details here once that is finished.

Simple Web Audio Wrapper

Seen this question asked numerous times, how to set up and use the Web Audio API, so I ripped some code out of my engine Booty5 and slimmed it down a bit and here it is, I have also pushed it to Github here.

/**
 * A Sound represents a sound effect object and can be used to play back audio
 *
 * Generally a sound should be added to either a {@link b5.Scene} or the global {@link b5.App}'s resources so that it can be managed by them.
 *
 * Example showing how to load and play a sound effect
 *
 *      var sound = new b5.Sound("explosion", "sounds/explosion.mp3", true);
 *      var instance = sound.play();
 *
 * For a complete overview of Resources see {@link http://booty5.com/html5-game-engine/booty5-html5-game-engine-introduction/resources-the-stuff-that-games-are-made-of/ Booty5 Resources Overview}
 *
 * @class b5.Sound
 * @constructor
 * @returns {b5.Sound}                      The created sound
 * @param name {string}                     Name of sound resource
 * @param location {string}                 The sound file location
 *
 * @property {b5.App|b5.Scene}          parent          - Parent resource manager (internal)
 * @property {object}                   snd             - Sound instance (re-usable sound only) (internal). For Web Audio stores a {source:AudioBufferSourceNode, gain:GainNode} object for auto play sounds
 * @property {object}                   buffer          - AudioBufferSourceNode containing decoded audio data (Web Audio only)
 * @property {string}                   name            - Name of this sound resource
 * @property {string}                   location        - The location of the sound file that is used to create the audio object
 * @property {boolean}                  loop            - If set to true then sound will be looped
 * @property {boolean}                  preload         - If set to true then this sound will be preloaded
 * @property {boolean}                  auto_play         - If set to true then this sound will be preloaded
 * @property {boolean}                  loaded          - If true then this resource has finished loading
 */

var loadFile = function(filename, blocking, callback, binary)
{
    var req = new XMLHttpRequest();
    req.open("GET", filename, !blocking);
    req.overrideMimeType("application/json");
    if (binary)
        req.responseType = "arraybuffer";
    if (!blocking)
    {
        req.onreadystatechange = function()
        {
            if (req.readyState === 4)
            {
                if (req.status === 200 || req.status === 0) // 0 for node-webkit
                {
                    if (binary)
                        callback(req.response);
                    else
                        callback(req.responseText);
                }
                else
                    callback(null);
            }
        };
    }
    try
    {
        req.send();
    }
    catch(e)
    {
        return false;
    }

    if (blocking)
    {
        if (req.status === 200)
        {
            if (binary)
                callback(req.response);
            else
                callback(req.responseText);
        }
        else
            callback(null);
    }

    return true;
};

b5.Sound = function(name, location)
{
    // internal variables
    this.parent = null;                 // Parent container
    this.snd = null;                    // Sound instance (re-usable sound only). For Web Audio stores a {AudioBufferSourceNode, GainNode } object for auto play sounds
    this.buffer = null;                 // AudioBufferSourceNode containing decoded audio data (Web Audio only)

    // Public variables
    this.name = name;					// The sound name
    this.location = location;			// Location of the sound
    this.loop = false;                  // If set to true the this sound will replay continuously
    this.preload = false;               // Set to true to preload sound
    this.loaded = false;                // Set to true once audio cam be played
    this.auto_play = false;             // Set to true to auto play sound when loaded
    this.load_retry = 0;
};

/**
 * AudioContext used by Web Audio API
 * @type {object}
 */
b5.Sound.context = null;
b5.Sound.muted = false;

/**
 * Initialises the sound system
 * @parm app {b5.App}   The App that will manage the audio engine
 * @returns {boolean}   true for success or false if error
 */
b5.Sound.init = function(app)
{
    if (app.use_web_audio)
    {
        try
        {
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            if (window.AudioContext === undefined)
                return false;
            b5.Sound.context = new AudioContext();
        }
        catch(e)
        {
            return false;
        }
        return true;
    }
    return false;
};

/**
 * Loads the sound
 */
b5.Sound.prototype.load = function(force)
{
    var debug = b5.app.debug;
    //var snd;
    var that = this;
    var filename = this.location;
    var auto_play = this.auto_play;
    if (!loadFile(filename, false, function(data) {
        if (data !== null)
        {
            b5.Sound.context.decodeAudioData(data, function(buffer) {
                that.buffer = buffer;
                if (auto_play)
                    that.play(force);
            }, function(e)
            {
                console.log(e)
            });
        }
        else
        {
            that.load_retry++;
            if (that.load_retry < 3)
                that.load();
        }
    }, true))
    {
        that.load_retry++;
        if (that.load_retry < 3)
            that.load();
    }
};

/**
 * Starts playback of the sound
 * @returns {object} An Audio object representing the playing sound or a {source, gain} object if using Web Audio API
 */
b5.Sound.prototype.play = function(force)
{
    if (force != true && b5.Sound.muted)
        return null;
    if (this.buffer === null)
        return null;
    var context = b5.Sound.context;
    var source = context.createBufferSource();
    var gain = context.createGain();
    source.buffer = this.buffer;
    source.loop = this.loop;
    source.connect(gain);
    gain.connect(context.destination);
    gain.gain.value = 1;
    source.start(0);
    if (this.auto_play)
        this.snd = { source: source, gain: gain };
    return { source: source, gain: gain };
};

/**
 * Stops playback of thr sound (re-usable sound only)
 */
b5.Sound.prototype.stop = function()
{
    var snd = this.snd;
    if (snd === null || snd === undefined)
        return;
    snd = snd.source;
    snd.stop();
};

Happy coding!

Simple Messaging System with Redis and Node.js

Hey all, been a while since I posted anything constructive, I’ve been so busy wasting my time creating games for Facebook Instant Games Messenger (I will do a proper write up with my analysis and final findings / thoughts on this very soon). Not all has been lost working on Instant Games however. Two of my games required an instant messaging system that enables me to send real-time messages between players which ironically the Instant Games SDK doesn’t cater for. So I created one using Node.js and Redis (these two bad boy pieces of tech together are like sweet music). You can grab the code from Github here.

Note that you will need to install this to your own server, I like to run most of my node modules using PM2. So to get the messaging system up and running just run pm2 msys. The server looks to the /msys endpoint, but you can change this in msys.js if you need it to go elsewhere. No, I don’t answer questions on how to set up servers and mess with Apache config files because I hate all that junk, it gets in the way of my actual coding which I do enjoy :) . If you cannot do this stuff yourself then you probably should be paying someone else do this for you.

Oh word of warning, any messages sent will time out after 7 days (this is to keep Redis memory usage down), but you can extend this to whatever time limit you like. Messages are queued, when you collect the pending messages it collects them all and deletes them from the database.

Ok, how to use client side? Here is a simple class (erm I mean collection of functions) with an awesome original name that I ripped out of one of my games for you guys to use:

var Backend = {};

Backend.SendMessage = function(data, done_callback)
{
    var url = "https://yourdomain.com/msys?c=s&t=<your token>";
    url += "&g=1";
    url += "&u=" + data.to_id;
    url += "&d=" + encodeURIComponent(JSON.stringify(data));
    b5.Utils.SendGetRequest(url, function(response) {
        if (done_callback !== undefined)
            done_callback(response);
    })
}

Backend.SendMessageMulti = function(recipients, data, done_callback)
{
    var users = "";
    var len = recipients.length;
    for (var t = 0; t < len; t++)
    {
        users += recipients[t];
        if (t < (len - 1))
            users += "_";
    }
    var url = "https://yourdomain.com/msys?c=s&t=<your token>";
    url += "&g=1";
    url += "&m=" + users;
    url += "&d=" + encodeURIComponent(JSON.stringify(data));
    b5.Utils.SendGetRequest(url, function(response) {
        if (done_callback !== undefined)
            done_callback(response);
    })
}

Backend.GetMessages = function(done_callback)
{
    var url = "https://yourdomain.com/msys?c=g&t=<your token>";
    url += "&g=1";
    url += "&u=" + Social.GetPlayerID();
    b5.Utils.SendGetRequest(url, function(response) {
        if (response.status == 200)
        {
            var data = decodeURIComponent(response.responseText);
            var obj = JSON.parse("[" + data + "]");

            if (done_callback !== undefined)
                done_callback(obj);
        }
        else
        {
            if (done_callback !== undefined)
                done_callback();
        }
    })
}

There are a few functions in here that you will need to implement yourself:

  • Social.GetPlayerID() – Replaced with your players user ID, if you are using Facebook Instants SDK then use FBInstant.player.getID()
  • b5.Utils.SendGetRequest() – Performs a GET request, e.g:
b5.Utils.SendGetRequest = function(url, callback)
{
    var req = new XMLHttpRequest();
    req.onreadystatechange = function()
    {
        if (callback != undefined && req.readyState == 4)
            callback(req);
    }
    req.open("GET", url, true);
    req.send();
}

Anyway, that’s it, hope you find more useful than I did. Happy coding :) .

Lets Bounce Endless Bouncing Facebook Instants Game

Lets Bounce Facebook Instants Game

Lets Bounce Facebook Instants Game

Finally released the revamp of Friend Falls, this game centres purely around multiplayer, no single player functionality is available. I’m trying to test if multiplayer only games fair better than single or mixture of single / multiplayer game play.

In this game you play a ball called Ball (yes imaginative I know) that is forever bouncing, your task is to navigate a vertical world fraught with danger. You are powered by ether, but each bounce or knock you take uses up ether. Additional ether can be collected as you progress through the world. Ether is dual purpose, it gives you more energy to bounce and you can use it to buy silly hats form the hat shop to spice your character up a bit.

There is no single player component so you have to invite someone else to play. The game has a back-end for transferring results and invites around between players, so you do not need to exit and re-run the game from a message to continue play.

The game also has a mini game editor in there which allows you to create your own levels and share them with friends. Once a player plays your custom level the level is sent back to you as a challenge so you get to suffer your own creations too, so be nice :) .

Anyway, check it but if you do, don’t forget to play again tomorrow or you will my day 1 retention :) .

Multi-game Facebook Instant Games Bot (free code)

So, I decided to post the code to my Facebook Instant Games Bot to save other devs a lot of research and time. The bot is written using node.js, you will need to set up a hosting service that will run your bot. I chose Digital Ocean to host mine because Droplets are super simple to set up and cheap as chips. I service 5 games with the single bot and I never go over my $5 per month limit. If you do sign up with them then please use my referral link, you get $10 of free credit.

This bot server can handle many games at once, simply add new games to the pages.js source file. Click this link to download the bot.

Files in this archive include:

  • bot.js – The main bot which accepts requests and creates new players
  • bot_none_cluster.js – None cluster version of bot.js (can be used with pm2 -i option)
  • crawler – Crawls through the database checking for players that need to be messaged and messages them, also removes players that do not respond from the database
  • messaging.js – Sends messages out to players
  • pages.js – Stores page data

Usage:

  • node bot.js – Runs the bot which listens for connections and adds players to the database
  • node crawler.js – Periodically crawls through the database finding players that need to be messaged and sends them a message

Note that you will need to set up both node and redis on your server in order for the bot to work. Performance wise the bot is incredibly fast. I am servicing 5 games with mine and using only 1% CPU.

To help get you started see my other blogs:
Installing and running Node.js on a VPS
Installing Redis to Windows / Linux

Facebook Instant Games Category Breakdowns

I track all things Facebook Instant Games related, its a new little obsession of mine. I went ahead and calculated how many games are in each genre out of the current crop of just under 3000 available games. Below is a list of Facebook game genres along with how many games are in each:

  • Action – 577 games
  • Puzzle – 1035 games
  • Trivia & Word – 118 games
  • Simulation – 150 games
  • Board – 98 games
  • Sports – 282 games
  • Match 3 – 100 games
  • Card – 64 games
  • Slots – 43 games
  • Runner – 260 games
  • Strategy – 73 games
  • Role Playing – 91 games
  • MOBA – 4 games
  • Builders – 15 games
  • Bingo – 9 games
  • Poker & Table – 34 games
  • Card Battle – 4 games

Lets take a look at the list sorted by total MAU in those categories:

  • Puzzle – 1035 games (49116400 total MAU – avarage per game is 47455)
  • Sports – 282 games (44689600 total MAU – avarage per game is 158473)
  • Trivia & Word – 118 games (41406500 total MAU – avarage per game is 350902)
  • Action – 577 games (38617000 total MAU – avarage per game is 66927)
  • Board – 98 games (17343200 total MAU – avarage per game is 176971)
  • Simulation – 150 games (16033700 total MAU – avarage per game is 106891)
  • Runner – 260 games (14430399 total MAU – avarage per game is 55501)
  • Card – 64 games (10803200 total MAU – avarage per game is 168800)
  • Match 3 – 100 games (6334800 total MAU – avarage per game is 63348)
  • Role Playing – 91 games (4992400 total MAU – avarage per game is 54861)
  • Strategy – 73 games (4511700 total MAU – avarage per game is 61804)
  • Slots – 43 games (1562100 total MAU – avarage per game is 36327)
  • Bingo – 9 games (1474800 total MAU – avarage per game is 163866)
  • Poker & Table – 34 games (1464900 total MAU – avarage per game is 43085)
  • Card Battle – 4 games (924500 total MAU – avarage per game is 231125)
  • MOBA – 4 games (322000 total MAU – avarage per game is 80500)
  • Builders – 15 games (193300 total MAU – avarage per game is 12886)

What can we ascertain from these figures? Well, Puzzle games seem to be the most popular amongst developers, unfortunately users do not share that view with a very low average MAU per game. Trivia & Word is the leading category in terms of of average MAU per game whilst having far fewer games has an average MAU many times greater.

Introduction to Facebook Instant Game Development

Introduction to Facebook Instant Game Development

This is the first part of my tutorial series that covers Facebook Instant Game Development. Over the coming months I will be covering all areas of the IG SDK, providing information, examples and hopefully working code :) . I will also be throwing in some back-end tutorials, showing how to write bots, messaging systems and so on.

Its the new developer craze, well sort of, its still a bit niche at the moment because compared to the app stores, users are very low and paid user acquisition is not yet an option.
Instant games (or minis) are small games that load more or less instantly within apps such as messenger apps (for example Facebook Messenger). They are created using HTML5 / Canvas / WebGL and JavaScript so they can be easily delivered to users without app store approval, although you do need to get Facebook approval which is sometimes much quicker.

So what are the advantages of developing and releasing products for platforms such as Facebook Instant Games? First and foremost is that it is quite easy to get something on there quickly, although delving deeper into the Facebook Instants technology does become a lot more complex when you start to create more social games, you will need to start thinking about writing your own back-ends for example. It is also fun, the bit I like about it the most. The platform is also good for testing iterative improvements out on very casual gamers as once your game is reviewed and approved further updates do not currently need any approval.

What are the downsides? Discovery and retention are bad, I’m talking single digit day 1 retention figures and players numbering in the hundreds per day in mainly none English speaking low revenue countries. The system is also currently winner takes all where a few games at the top take up most of the visibility so breaking through is incredibly difficult. My advice is do not think that you can dump any old game onto IG, for example simply porting an existing web game not designed for IG, it just doesn’t seem to work. The top games all feature integration at various levels to the IG SDK, this is your only source of retention and discovery.

Features

What sort of features does Facebook Instant Games have from a game developers perspective?

  • Its main and most important feature is that it enables social play between people and groups of people. To get to the basics you do not need to create a complex back-end, its all available from the SDK and handled by Facebook’s servers.
  • Important moments from within the game can be shared amongst friends and in other contexts such as groups.
  • Leaderboards are supported. Global, friends and context scoped leaderboards are all available.
  • Monetisation is available out of the box and easy to set up. You can show interstitial ads, rewarded video ads and offer in-app purchases, although IAP’s are limited to Android only. Ads are limited to mobile and not available on desktop.
  • Metadata support, almost everything you send anywhere can have some kind of meta data attached. For example, if I post my score to a messenger conversation I can attach some replay data which can be picked up by anyone that clicks on the message when the game is launched.
  • Bots – Whilst a blessing and a curse, chat bots can help to remind users to come back to your game and play increasing your retention. Not a fan of them but they have their uses. Its possible to build a complex back-end bot which practically becomes an extension of the game play itself.
  • Analytics – You can track various default events for your game as well as send custom events which you can view in the analytics section of the developer dashboard.

Context

Facebook Instant Games revolve very heavily around the concept of the context. What is a context? A context is basically a collection of players in some area of Facebook. A few examples:

  • Two people in a messenger chat. This is a context with two people
  • A Facebook post – This is a context with many people potentially on the same thread

Each context has its own unique ID that allows you to identify it and switch into it to perform operations in the context, What sort of operations? Once you are in the context your game can perform various operations such as get all of the players in the context, post messages to the context about the current state of the game. You can also store and retrieve leaderboard scores that are specific to that context only. Context ID’s are unique and persistent so you can store a context’s ID and come back to it at any time.

You generally post an update to a context when something important happens in your game. For example, you have just beaten a level and you want your friends to know. This helps with discovery because all players in the thread or chat or whatever context you are in will see the rich message (a message usually consists of an image from the game, a title, a sub title and a call to action button). The rich message can also contain hidden meta data about the game, this will be passed to the game when anyone clicks the posted call to action to launch the game. This enables information to be passed around from player to player in a none real-time / sort of turn based environment. I say sort of because you need to exit the game and run it from the other players message to take the next turn in the game. You can of course get around this by creating your own back-end to marshal the messages around.

Connected Players

Connected players are basically players that play your game and are connected to you on Messenger. This list is very useful because you can do things like show a list of familiar players that the player may wish to play, or maybe send a gift / ask for help.

Getting Started

You can get a hold of the Instants SDK from the Facebook developer website, note that you do need to be a Facebook developer to submit games, so you should sign up here.

Whats next?

In the next part of this tutorial series I will introduce you to an overview of the Facebook Instants SDK and show you how you can begin integrating your game into the Facebook Instants Game platform.

Wrapping up

Facebook Instants are an exciting new technology full of possibilities for game developers from all backgrounds and fun to play with as a gamer and game developer. Fingers crossed that Facebook Instant Games continues to grow and improve with each new iteration. It is still in its infancy however so be warned and do not invest crazy amounts of time and money into it like I did. Ease in gradually and try to re-use as much as possible of what you already have, but don’t just dump games that are not designed for IG onto the platform, its just messy and unprofessional.

Facebook Messenger Instant Games Charts

I’ve been tracking the positions and MAU of Facebook Messenger Instant Games for a while now. I track them for many reasons include:

  • Get an overall picture of where all IG games are at
  • Get an overall picture of how IG itself is performing
  • Analyse which games are rising / falling
  • Guess at how much developers are roughly earning
  • Spot clones and dodgy developers
  • See how my own games and performing

I use this information to improve my own games. Whilst its not offered much success for me it may do to some. With that in mind I am posting a much stripped down version of the charts here to enable other developers can utilise some of the information and help improve their own games / track where their games are at in the grand scheme of things.

Facebook Messenger Instant Game Charts 2018