Javascript

Last updates on Skald Engine:

Color utility functions

PixiJS handle colors by its int value (e.g., 0xFFFFFF), so I created a bunch of function to convert or manipulate colors in this format. Right now you can:

  • Convert color from/to RGB format (array, [255, 255, 255]).
  • Convert color from/to HEX format (string, ‘#FFFFFF’).
  • Convert color from/to HSL format (array, [255, 1, 1]).
  • Get the individual color channels (red, blue, green, hue, saturation, lightness).
  • Saturate a color by a given amount.
  • Desaturate a color by a given amount.
  • Covert the color to greyscale.
  • Lighten a color by a given amount.
  • Darken a color by a given amount.
  • Spin the color by the hue space by a given angle.
  • Blend two colors.
  • Tint (blending a color to white).
  • Shade (blending a color to black).

 

Utility for random generators

I also added a bunch of function to generate random numbers and other  stuff related:

  • `random.choose()` to choose a value from an array.
  • `random.inclusiveRandom()` which is similar to Math.random(), but it can include the 1 (i.e., it generates a number in interval [0, 1]).
  • `int()` to generate a random integer.
  • `polar()` to generate a number between -x and x.

Easing function and modifiers

I add more easing functions, a general bell curve and a gaussian shaped (using the normal distribution formula without the normalization term). So they can be used to generate interesting effects.

I also added two function that modifies the easing functions, one for mirroring the result of the easing (it repeat the ease function 2 times, but it invert the result of the second half), and one for repeating (pretty straightforward). I am still testing this format, so I don’t know if I’m gonna keep it.

Particle systems!

Added an initial implementation of particle system. there are some improvements to be made, but it is working pretty good.

Game config changes

I decided to remove the manifest as parameter of the game and added it as an item of the configuration. This should keep consistence among the API.

Additionally, I added a startScene and a preloadScene option, so the game can initialize and run a preload scene during the manifest loading, and start automatically the main scene when the game starts.

To help you in this initialization process, I also added a `start` event, triggered after the preload (if there is any item on the manifest), and added a default preload scene.

Scene stacking

I thought I could live without it, but I was wrong, so we have scene stacking now. Now you can add or remove scenes over the base scene (the one called with `play` method). The scenes are attached to the base scene, so if you remove the base, all scenes in the stack will die too.

 

Next steps

For the next alpha release, I want to add an event pool for event recycling (so we don’t have to create a new event instance everytime an event is triggered), and simplify the scene API. Right now the scene API is very limited and unintuitive.

Read more

About two year ago I started a game engine called Creatine, which was built upon CreateJS. I used this engine for quite some time, creating 4 jam games with it. However, I reached a point where I couldn’t improve Creatine anymore due to the limitations of CreateJS, in particular because CreateJS cannot use WebGL.

After some time without seeing anything about game development (I started in a new job, and hence my absence from this blog), I decided to start a new engine in order to enter make games for game jams again. This time, I decided to go with PixiJS, which is the status quo of 2D WebGL rendering in the JavaScript world.

But why I don’t simply use Phaser? Well, Phaser is undoubtedly a great project, with a mature code base and huge community, but I personally don’t like it. Its internal structure is confuse and I can’t understand properly (without spending a lot of time) how it works. Notice that, this is my opinion. I don’t like Phaser, but I am not saying you shouldn’t use it.

So I started Skald, my new engine, with some important pillars in mind:

  • The engine must allow me to create fast prototypes for my jam games, however, it must have a good architecture so I can create larger games with it if I want to.
  • Kind of consequence of the point above, the engine must allow me to reuse individual components, something similar to how Construct 2 works.
  • The engine architecture must be simple and intuitive, so anyone could understand what is happening under the hood.

Additionally, I would like that the engine be flexible enough so people can use it ignoring any part of it (e.g., you may rewrite how scenes and ECS works with relatively simplicity).

Right now Skald is on Alpha 2 – which means that I don’t recommend anyone to use it yet! – and the core features at this point are:

  • Game class with managers to control audio, inputs, scenes, devices, etc.
  • An extensible asset loader.
  • ECS objects. Not perfect or very strictly classic implementation, but it is working well.
  • Multiple and extensible audio systems. Right now with support to webaudio and html5 audio.
  • Support to 3rd-party plugins.
  • Scene transitions (similar to creatine).
  • Tweens, color and easing functions, and other utility functions and structures.
  • Most of the features of PIXI.

The final version of Skald won’t be released any time soon, but for the next alpha release I would like to add the following features:

  • Particles! Super important to have a particle system.
  • Scene stacking, so we can add, for example, a pause screen over the game without removing the game scene off the screen.
  • A better initialization procedure with a default loading scene (if there is anything to load).
  • Anonymous scenes and entities.

The project is hosted on github:

 

Read more

Ludum Dare is great! Not just because it motivates me to create (and finish) a new game, but also because I use it to update Creatine. So, as usual, after the compo I’m releasing another version creatine, now the release 1.0.0!

This version is big. It has a lot of new stuff and a lot of changes for the old features. But before talking about the modifications and additions to the library, let me talk about how I was felling about creatine 0.2…

To be honest, I wasn’t happy about the previous version, I added several classes to handle storage, sound, layout, scenes, among other things. But they weren’t working together, there were some annoying bugs (in special with transitions) and I was spending a good time rewriting the same base structure for new games, over and over.  So I decided to rethink some things: how can I make my development easier and faster? My conclusions and desires after that:

  • I want to use a visual editor to build my scenes, something like Overlap2D or one tool of my own.
  • I need more flexibility for fast prototypes (sometimes I just want to test some idea).
  • Modularity is cool, but is not a great deal. A class that controls all modules would be more useful and would save some time by eliminating the base common structure that I was rewriting every project.
  • I need more fluffy things, more juice, which means that have to be easy to add particles and visual or sound effects to the game.
  • I want to have a physic system and other predefined behaviors easy to use in my games (such as a platform system, or 2d top-down movement and collision system).
  • Other details that I don’t remember right now (it is Sunday 11PM, give me a break!).

With these things in mind, I started to update creatine.

Game

The main addition to creatine is the Game object. The game is now the core of my library, because it is the responsible to create and initialize all game systems. For example: it is the game that creates the canvas element; the game also stores all creatine helpers (now called managers), such as the director (SceneManager), the device,  display and many others.

The game class is based on Phaser core, so if you know Phaser you may find this familiar. A game has 5 states: ”boot”, “preload”, “create”, “update” and “draw”. In the boot state you can initialize 3th-party libraries and some configuration of the engine. In preload, you will set which files should be loaded by the engine and may be show a preload scene. In the create state you will create and initialize all game objects, including scenes and object pools. The update and draw states are the main loop, and are executed every tick. You can use these state by passing functions to the game:

var game = new tine.Game(null, {
  boot    : function() {},
  preload : function() {},
  create  : function() {},
  update  : function() {},
  draw    : function() {}
})

The first argument of the Game class is the configuration object. This could be only an url to a JSON file containing the configuration. Notice that, with this, I will try to keep all engine data-driven, so you will be able to configure everything using this parameter. Right now, it has the following default values:

{
  project          : 'creatine_game',
  width            : 800,
  height           : 600,
  container        : null,
  framerate        : 60,
  background_color : '#000',
  resources        : {
    base_path : './',
    manifest  : []
  }
}

To set configuration you can do:

var game = new tine.Game({framerate:30, width:300, height:500});

or yet:

var game = new tine.Game('myconfig.json')

where ‘myconfig.json’ is the json file containing the configuration values.

Resources and Factories

Creatine now have an interface to PreloadJS (the ResourceManager) and a factory manager. The resource manager helps you to load general assets in a more pleasant way and also helps you to load specific assets (such as spritesheets and audiosprites) in an easier way. For example, now you can set which files you want to preload in the preload state:

var game = new tine.Game(null, {
  preload: function() {
    game.load.image('id', 'src.png');
    game.load.spritesheet('id2', 'src.png', data);
    game.load.json('id3', 'data.json');
    ...
  }
});

Or you could define these assets in the manifest (pretty much like how you do with PreloadJS):

var game = new tine.Game({resources: {
  manifest: [
    {id:'id', src:'src.png'},
    {id:'id2', src:'src.png', data:{stuff here}, type:'spritesheet'},
    ...
  ]
}});

With your stuff loaded, you can create objects easier:

var game = new tine.Game(null, {
  preload: function() { ... },

  create: function() {
    var bitmap = game.create.bitmap('id', {x:100, y:400, regX:'center', regY:'bottom'});
    var sprite = game.create.sprite('id2', 'animation');
    var map = game.create.tilemap('id3');
  }
});

 

Scenes and Transitions

Scenes now have some default method that you should override to use, such as “enter”, “pause”, “resume”… To create a scene, you must define a new class inheriting the scene class, an easy way to do that is by using the new shortcut:

var MyScene = tine._scene({
  initialize: function() { ... },
  enter: function() { ... },
  update: function() { ... },
  ...
});

You can also create your scenes before starting the application and register them to the director, using an unique identifier:

var game = new tine.Game(null, {
  create: function() {
    // Create scenes here
    ...

    // Add your scenes to the director
    game.director.add('menu', new MyMenuScene());
    game.director.add('level', new MyLevelScene());

    // Run a scene
    game.director.replace('menu')
  }
});

Transitions are now working as they should be! You can use any transition in any function (replace, push or pop), repeatedly, or without having to wait the current transition.

Input handlers

We have input now! Keyboard, gamepads, mouse and touch. They don’t work together yet, but they are pretty cool already. Instead of putting code here, I suggest that you take a look into the creatine example folder and into the API documentation.

In the next releases I want to create a common Input or Control object that group all type of inputs together. So instead of checking the state of the keyboard, mouse and touch, you could simply check game.control.isDown(‘action a’) . Moreover, you should be able to redefine the input commands.

Particles!

Particles are so so so so cool! Creatine uses the cocos2d particle style. So if you want to create some fire you do:

var emitter = null;

var game = new tine.Game(null, {
  preload: function() {
    game.load.image('particle', 'assets/particle_red.png');
  },

  create: function() {
    var image = game.create.bitmap('particle', {regX:'center', regY:'center'});
    emitter = new tine.Emitter(image, 500);
    emitter.emitX = 512;
    emitter.emitY = 288;
    emitter.angle = -90;
    emitter.angleVar = 10;
    emitter.speed = 100;
    emitter.speedVar = 20;
    emitter.life = 2000;
    emitter.lifeVar = 500;
    emitter.emissionRate = 150;
    emitter.startScale = 0.3;
    emitter.compositeOperation = 'lighter';
    
    emitter.start(-1);
    game.stage.addChild(emitter);
  },

  update: function() {
    emitter.update(game.time.delta);

    if (game.mouse.isDown(tine.buttons.LEFT)) {
      emitter.emitX = game.mouse.x;
      emitter.emitY = game.mouse.y;
    }
  }

})

Unfortunately, the current particle system has some limitations. For example, it cannot change the particle colors due to performance. It also must be updated manually, sometimes I forget that!

Sounds and Storage

The SoundManager is simpler now, it does not separate music from sound effects, but you still can add sound groups to it. The coolest thing is that sound works together with the StorageManager, so when you change the volume or the mute, the sound manager stores this information locally and you don’t have to worry about that anymore!

Legacy Stuff

Some things will be changed to a better structure, such as the layout managers and the custom display objects. They are still in creatine but they weren’t updated this time.

Moar of Creatine

To now more about new stuffs in creatine, check it out:

You can also contact me for any doubt or suggestion.

Read more

I’ve been talking a lot about Behavior Trees (BTs) lately, partially because I’m using them for my PhD. But although, BTs provide a powerful and flexible tool to model game agents, this method still have problems.

Suppose you want to model a bunch of sheeps (just like my last Ludum Dare game “Baa Ram Ewe”), these sheep have simple behaviors: “run from cursor”, “stay near to neighbor sheeps”, “don’t collide with neighbor sheeps” and “follow velocity and direction of neighbors”. A sheep can also have 4 states: “idle” when it is just eating grass, “obey” when it is being herded by the player (using the mouse), “stopping” between obey and idle, and “fear” when a predator is near. The behaviors are always executing, but they may have different weight for different states of the sheep. For example, when a sheep is “obey”-ing, it try to be near other sheeps more than when it is eating grass or running scared.

Modeling this as a Behavior Tree is hard because:

  1. BTs don’t really model states well. There is no default mechanism to define or consult which state an agent is; and
  2. All behaviors are executed each tick, thus this agent wouldn’t exploit the BT advantages of constrained executions.

Notice that, you still can model these sheeps with BTs, but the final model would be a lot more complex than it would be using other simple methods.

In previous posts, I also talked about how Behavior Trees have several advantages over Finite State Machines (FSMs). But, in cases like this a FSM is a lot useful and considerably easier to use than BTs.

Implementation

Like my Behavior Tree implementation, I want to use a single instance of a FSM to control multiple agents, so if a game has 100 of creatures using the same behaviors, only a single FSM instance is needed, saving a lot of memory. To do this, each agent must have its own memory, which is used by the FSM and the states to store and retrieve internal information. This memory is also useful to store sensorial information, such as the distance to nearest obstacles, last enemy position, etc.

First, consider that all states and machines have a different id, created using the following function:

function createUUID() {
  var s = [];
  var hexDigits = "0123456789abcdef";
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  // bits 12-15 of the time_hi_and_version field to 0010
  s[14] = "4";

  // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);

  s[8] = s[13] = s[18] = s[23] = "-";

  var uuid = s.join("");
  return uuid;
}

and to simply inheritance, we will use the Class function:

function Class(baseClass) {
  // create a new class
  var cls = function(params) {
    this.initialize(params);
  };
  
  // if base class is provided, inherit
  if (baseClass) {
    cls.prototype = Object.create(baseClass.prototype);
    cls.prototype.constructor = cls;
  }
  
  // create initialize if does not exist on baseClass
  if(!cls.prototype.initialize) {
    cls.prototype.initialize = function() {};
  }

  return cls;
}

We will use a Blackboard as memory for our agents. Notice that, this is the same blackboard used in my behavior trees.

var Blackboard = Class();
var p = Blackboard.prototype;

p.initialize = function() {
  this._baseMemory = {};
  this._machineMemory = {};
}

p._getTreeMemory = function(machineScope) {
  if (!this._machineMemory[machineScope]) {
    this._machineMemory[machineScope] = {
      'nodeMemory'     : {},
      'openNodes'      : [],
      'traversalDepth' : 0,
      'traversalCycle' : 0,
    };
  }
  return this._machineMemory[machineScope];
};

p._getNodeMemory = function(machineMemory, nodeScope) {
  var memory = machineMemory['nodeMemory'];
  if (!memory[nodeScope]) {
    memory[nodeScope] = {};
  }

  return memory[nodeScope];
};

p._getMemory = function(machineScope, nodeScope) {
  var memory = this._baseMemory;

  if (machineScope) {
    memory = this._getTreeMemory(machineScope);

    if (nodeScope) {
      memory = this._getNodeMemory(memory, nodeScope);
    }
  }

  return memory;
};

p.set = function(key, value, machineScope, nodeScope) {
  var memory = this._getMemory(machineScope, nodeScope);
  memory[key] = value;
};

p.get = function(key, machineScope, nodeScope) {
  var memory = this._getMemory(machineScope, nodeScope);
  return memory[key];
};

We will also use a state object that implements the following methods:

  • enter“: called by the FSM when a transition occurs and this state is now the current;
  • exit“, called by the FSM when a transition occurs and this state is not the current one anymore; and
  • tick“, called by the FSM every tick in the machine. This method contains the actual behavior code for each state.
var State = statejs.Class();
var p = State.prototype;

p.initialize = function() {
  this.id = statejs.createUUID();
  this.machine = null;
}

p.enter = function(target, memory) {}

p.tick = function(target, memory) {}

p.exit = function(target, memory) {}

Our FSM will have the following methods:

  • add(name, state)“: adds a new state to the FSM, this state is identified by a unique name.
  • get(name)“: returns the state instance registered in the FSM, given a name.
  • list()“: returns the list of state names in the FSM.
  • name(memory)“: return the name of the current state. It can be null if there is no current state.
  • to(name, target, memory)“: perform a transition from the current state to the provided state name.
  • tick(target, memory)“: tick the FSM, which propagates to the current state.

Notice that, some methods must receive the blackboard and the target object as parameters, which can be a little annoying – this is the downside of using a single FSM to control multiple agents – but the cost is small compared to the gain in memory.

The target parameter is usually the agent being controlled, but in practice it can be any kind of object such as DOM elements, function or variables.

var FSM = statejs.Class();
var p = FSM.prototype;

p.initialize = function() {
  this.id = statejs.createUUID();
  this._states = {};
}

p.add = function(name, state) {
  if (typeof this._states[name] !== 'undefined') {
    throw new Error('State "'+name+'" already on the FSM.');
  }

  this._states[name] = state;
  state.machine = this;

  return this;
}

p.get = function(name) {
  return this._states[name];
}

p.list = function() {
  var result = [];
  for (var name in this._states) {
    result.push(name);
  }

  return result;
}

p.name = function(memory) {
  return memory.get('name', this.id);
}

p.to = function(name, target, memory) {
  if (typeof this._states[name] === 'undefined') {
    throw new Error('State "'+name+'" does not exist.');
  }

  // exit current state
  var fromStateName = memory.get('name', this.id);
  var fromState = this.get(fromStateName);
  if (fromState) {
    fromState.exit(target, memory);
  }

  // change to the next state
  var state = this._states[name];
  memory.set('name', name, this.id);
  state.enter(target, memory);

  return this;
}

p.tick = function(target, memory) {
  var stateName = memory.get('name', this.id);
  var state = this.get(stateName);
  if (state) {
    state.tick(target, memory);
  }
}

Example

Using a simple Boiding algorithm, we have 3 states: “idle”, “obey” and “stopping”.

var StoppingState = Class(State);

StoppingState.prototype.enter = function(target, memory) {
  // when this state is initiated, it resets the timer
  memory.set('starttime', new Date().getTime(), this.machine.id, this.id);
}

StoppingState.prototype.tick = function(target, memory) {
  var mx = game.stage.mouseX;
  var my = game.stage.mouseY;

  // transition to obey
  if (euclidDistance(target.x, target.y, mx, my) < SHEEP_OBEY_DISTANCE) {
    this.machine.to('obey', target, memory);
  }

  // transition to idle
  var starttime = memory.get('starttime', this.machine.id, this.id);
  var curtime = new Date().getTime();
  if (curtime - starttime > 3000) {
    this.machine.to('idle', target, memory);
  }

  // call the boid algorithm with specific weights
  flock(target, memory.get('neighbors'), [0.0, 0.1, 1.0, 0.4])
}

Use the mouse to move the white balls:

Continue reading Finite State Machines in Javascript

Read more

Following the new milestone of CreateJS, I just released Creatine 0.2.0!

This version has some cool new additions to the library:

  • Tile Maps: now you can load maps created with Tiled by using the new TMXMap. It supports all maps projections of tiles (orthogonal, isometric and staggered) and all type of layers (tile, image and object). Check it out the examples.
  • Jukebox: a helper class to handle music and sound playback. With this class, you can set different volume setting for music and sounds, and play random sounds from a group.
  • Storage: a helper class to handle persistent data using the HTML5 localStorage. With this class you overcome the type limitation in localStorage (it only accept string variables) and , thus, can save and retrieve objects, numbers, arrays, etc.
  • Entity-Component-System: a ultra basic implementation of ECS model, I hope to provide more features in the future.

Moreover, there are some other modifications on the existing features:

  • Sizers now manage scale and registration point properties of children.
  • Fixed an initialization bug present in several transition.
  • A complete update to the class and inheritance model of creatine, following the new style of CreateJS.

Together with this new version, I also published the new website for creatine (the old one http://guineashots.com/creatine now redirects to the new site):

http://creatine.guineashots.com

Right now I’m updating my boilerplate to follow the new releases and to include a new improved architecture.

Read more