And Half A Fish Games.

And Half A Fish

Snake Island April 06, 2017 - "Doing the JSON."

The way I'm setting up Snake Island is similar to the way I created my two other point&click games. But of course, this time, I will have a lot of 'rooms' (or views), so it's not really practical to create them all in code like I did before.
So, I think I want to try and use a JSON-file to persist the rooms.

In case you're not familiar with JSON : it looks like text with lots of square brackets, curly braces, and commas. The test file I'm using to figure things out looks something like this :

[ {
    "roomName" : "room1",
    "bgImgPath" : "img/bg/room1.png",
    "nav" : { "1": "goto.1.0.0" }
}, {
    "roomName" : "room2",
    "bgImgPath" : "img/bg/room2.png",
    "nav" : { "1": "goto.0.0.0", "2": "goto.0.0.-1" }
}, ...

So, basically an array of objects, where each object will describe one room (or view) in the game. This JSON-file will of course change a lot during development, but for now, it is good enough to get things going.

slightly worried ... As you can imagine, a file like that is difficult to create and maintain by hand, so I need to create some sort of a mini-editor that can do this for me.
To be honest, I'm just a tiny bit uneasy about his whole JSON/editor thing ... I hope I can pull it off !

So, I couldn't figure out how to create and read a JSON-file from Haxe/OpenFL with the official documentation (and a lot of Googling).
In the end, after wasting quite a bit of time, I had to go to the OpenFL forum for some tips. They were really quick to help me out (thank you !!!), and told me you can't create a JSON-string directly from an object. You have to map the object to a structure first :

typedef RoomJson= {
    var roomName : String;
    var bgImgPath : String;
    var x : Integer;
    var y : Integer;
    var z : Integer;

class Room {
    private var roomName, bgImgPath : String;
    private var x, y, z : Int;

    public function new(...) {


    public function getRoomJson() : String {
        var props : RoomJson = {
            roomName : this. roomName,
            bgImgPath : this.bgImgPath,
            roomX : this.roomX,
            roomY : this.roomY,
            roomZ : this.roomZ,
        return Json.stringify(props);

In the end, I decided I didn't really like this approach, because I felt that the Room class was becoming too cluttered. So, I moved all JSON-related stuff into a JsonDecoder class with static functions :

class JsonDecoder {
    public static function JsonEncode(arr : Array<Room>) : String {
        var arr_json:Array<Dynamic> = new Array<Dynamic>();
	for (room in arr) {	
            var props : Dynamic = {};
            props.roomName = room.roomName;
            props.bgImgPath = room.bgImgPath;
            props.roomX = room.roomX;
        return Json.stringify(arr_json, null, " "); //pretty print

    public static function JsonDecodeRoom(jsonObj : Dynamic) : Room {
        var r_inst = Type.createInstance(Room,[jsonObj.bgImgPath, jsonObj.roomX, 
            jsonObj.roomY, jsonObj.roomZ]);
        populateRoom(r_inst, jsonObj);
        return r_inst;

    private static function populateRoom(r_inst : Room, jsonObj : Dynamic) : Void {

The way I finally solved it is probably not really 'best practice', but hey ... it's working (for now) and that's good enough for me !