Wednesday, December 23, 2015

Unit Testing FSharp for Unity3D

I'm going to try using FSharp in Unity, and I want to unit test my code before I drop my compiled dll into Unity's Asset folder. Testing is one thing that MonoDevelop is pretty good at. After installing mono-develop, I installed NUnit:

sudo apt-get install monodevelop-nunit.

You can also install it from MonoDevelop via the menu: Tools->Add-in Manager.

So in the project view, I right click on my Solution Items, and select Add->New Project...
I don't see any templates for FSharp Unit Testing, so I'll do this from scratch. I create a FSharp Library Project, and name it Test. For Unity compatability, we need to change the taget, so select Project -> Test Options -> Build -> General and change the target framework to Mono/.NET 3.5.

Next, I install NUnit. Right click on the new project, Test, and select Add Nuget Packages. I'll look for and install NUnit. And here I have a problem. NuGet won't install the correct version for my target (3.5), but it will tell me that it installed the wrong one... and that's why I don't use NuGet.

So instead, I visit http://nunit.org/?p=download, and grab the Previous Release: NUnit 2.6.4. I unzip it to my ~/Applications folder, and then reference the dll in my project: In the project view, right click on References and select Edit References... From here I select the .Net Assemblies tab, and browse for ~/Applications/NUnit-2.6.4/bin/nunit.framework.dll \

Now I'm ready to write tests, so I create a simple class:

open System    
open NUnit.Framework
open Entitas

[<TestFixture>]
type Tests() =

    let world = new World(64)

    [<Test>]//1st entity - no components
    member this.Test001() =

        let e1 = world.CreateEntity("Playerz")
        Assert.AreEqual(1, e1.Id)

Save my work, right click on my Test project, and select Run Item to run my tests. I can also reference Unity data types by referencing the UnityEngine.dll:

Right click on References and select Edit References... From here I select the .Net Asseblies tab, and browse (on my system) for /opt/Unity/Editor/Data/Managed/UnityEngine.dll

Now, I add 

open UnityEngine
...

    [<Test>]//2nd test - one conponent
    member this.Test002() =

        let e2 = world.CreateEntity("Playery")
        e2.AddComponent(1, new Vector3(1,0f, 1.0f, 1.0f))
        ...
When I'm satisfied that my basic functionality is working, I move the dll into my Unity projects Asset folder. I do this by selecting my game project (not the testing project) in the project view, go to Project -> Project Options. Select the Build->Output and browse to my Unity project Asset folder. I create a new folder - Assets/Libraries, and select it. Now when I build my game project, the dll is generated directly into my Unity project. I can switch to the Unity Editor, and click on Play to see my code at work.

Sunday, December 13, 2015

Using FSharp with Unity

Getting the FSharp binaries to work with Unity is pretty well covered here: Tutorial: Using F# with Unity3D. I was able to get up and running with Unity 5.2.2f1 on Linux Mint 17 and MonoDevelop 5.10.

I started working through the Unity Angry Birds tutorial, and ran into some problems with the mouse. Really, though, it turned out to be an error between chair and keyboard while trying to re-implement the csharp tutorial code in fsharp.

At first attempt, this line looked like it should be changed from this

    Vector2 catapultToMouse = mouseWorldPoint - catapult.position;

to this:

    let catapultToMouse = mouseWorldPoint - catapult.position

The problem with is that now, 'catapultToMouse' becomes a Vector3. The caused problems latter on when 'catapultToMouse.sqrMagnitude' had an unexpected value. I fixed this with a helper function that converts a Vector3 to a Vector2:

    let catapultToMouse = Vec32(mouseWorldPoint - catapult.position)


The other issue I ran into was my code was not deetecting a null value for a unity component. It turns out to be a known issue F# null test fails to detect null values

After these two issues were resolved, I was able to get the demo working. And finally, to enable touch support on Android, I added this code to the end of the Update method:

        if Input.touchCount > 0 then
            match Input.GetTouch(0).phase with
            | TouchPhase.Began -> this.OnMouseDown()
            | TouchPhase.Ended -> this.OnMouseUp()
            | TouchPhase.Canceled -> this.OnMouseUp()
            | _ -> ()


The entire project is located here

Friday, December 11, 2015

Nemerle or FSharp?

Both are comparable functional DotNet languages. I want to use one of them in Unity. So I worked through this tutorial -MAKING AN "ANGRY BIRDS" STYLE GAME - PART 1 with each language, plus C#. Here are my conclusions.

C#

  • Baseline. Everything works and can target android.

F#

  • I couldn't the get mouse to work correctly
  • It takes more boilerplate to interop with components (1)
  • I can't use latest binaries in Unity, due to Unity's funky 3.5ish framework level
  • But - code completion and compilation works in MonoDevelop 

Nemerle

  • Interop is transparent (2) and mouse works + touch works on android
  • The binaries are current - a new drop yesterday included the 3.5 framework
  • I can edit in Code and compile using Nant. No *.sln files to deal with.

I never finished the FSharp version, because I couldn't get past the mouse issue.
NOTE: This is fixed. See my next post
 If I were to use FSharp, it would be as a library that does not interface directly with Unity. I'd need a CSharp layer. Maybe if I actually wanted to use MonoDevelop. But I prefer Code, and debugging for Unity is working now.

I think I prefer Nemerle syntax, it doesn't seem as dense. I can even use white space with #pragma indent. But more importantly, Nemerle seems to work better with Unity, and I can use the latest binaries when targeting android.

It's a no brainer. For my purposes, Nemerle wins.


1 - Defining a Unity component property in F#

[<defaultvalue>][<serializefield>]
val mutable catapultLineBack:LineRenderer

2 - Defining a Unity component property in Nemerle

public mutable catapultLineBack: LineRenderer




Thursday, December 3, 2015

Stop The Madness: Using json in csharp

I want to read some json in csharp. It shouldn't bee too hard, there are some great libraries out there - Json.NET comes to mind. The problem with most of the existing libraries is that they do too much - I don't really need xml support, or linq or json path. In fact, all I want is the JSON.parse and JSON.stringify that I love so much in javascript. And so here it is - JSON2.cs.

The first thing you're going to say is 'Why are you boxing values? Where is dynamic?'. Actually, the 1st version used dynamic, and it's very cool to use, because you can access json values as dot properties. But dynamic is not allowed in the Unity version of csharp. Too bad, but I can see that dynamic could become a performance issue. So we will use bracketed notation. There are 2 helper classes - JSONObject and JSONArray. And 2 helper functions that really just wrap a cast - JSON.Object and JSON.Array.

The reason for all of this madness? So I can store a small database in my game with preferences and local leaderboard values:

 /**
 * Get Leaderboard
 * 
 * @param {int} count
 * @returns {JSONArray} the top count scores.
 */
 public static JSONArray GetLeaderboard(int count) {
  var jsonQueryAll = string.Format(@"{{""limit"":{0}, ""sort"": [[""score"", ""DESC""]]}}", count);
  return db.QueryAll("leaderboard", jsonQueryAll);
 }

To facilitate this, I've also ported localStorageDB.js to PlayerPrefDB.cs. You can see it in action, I'm using it in my first Unity game, Shmup Warz. Yes, I'm porting Shmup Warz also from typescript to csharp. Where does the madness stop?!

Thursday, November 5, 2015

CoffeeScript vs TypeScript - II

A while ago, I did a comparison of coffeescript and javascript https://blog.darkoverlordofdata.com/2014/03/coffeescript-vs-typescript.html. At the time, I felt that coffeescript was the better of the two. But typescript has seen some improvements, so it's time to compare them again.


Coffeescript

The main syntax difference is still there - whitespace vs curly brace. I like white space. My code editors don't. I have to be careful when I cut and paste coffeescript - make sure beutification is turned off, because if my white space is changed, so is my program logic.

Implicit returns - this is where the function automatically returns the value of the last assignment statment  - have caused countless bugs. I think most of the community would like to see this changed, but it likely will never happen. I now have a habit of typing the return statement first, and the going back to fill in the body of the procedure.

Very little changes in coffeescript. Support has been added to the new es6 yield. The compile switch --join has been removed, which required a re-write of my build process.


Typescript

Typescript now has many of the features I was looking for and finding in coffeescript, plus more.
We now have string interpolation, generics, and annotaions.
You can now use an expression as a superclass.
Lambda's are supported with fat arrow binding to 'this'.

My code editors love typescript. Good code completion and auto braces make it just as easy to type as coffeescript. All in all, I find much better tooling is available for typescript.



If it sounds like all my new code is in typescript, you'd be half correct. For complex client side applications, I like typescript. For server side and command line programs, I still like coffeescript, and use it instead of bash for creating my build scripts.

Typescripts real strength is it's community involvement. Many of the pluses for typescript are comunity driven, and this is the real reason I've been using it more. The lack of community involvment with coffescript is probably it's worst feature, and the main reason I started looking at typescript.

Thursday, September 17, 2015

Artemis TS

Artemists  is a port of Artemis framework from java to typescript. It requires TypeScript version 1.5 or greater due to the use of decorators, which I'm using to mimic java annotations.

As a demo, I've ported the game Spaceship Warrior by @Flet. You can play my port here. In addition to artemis, it uses pixi.js for graphics, and howler.js for sound. For decent performance, you'll need to have WebGL enabled. That shouldn't be a problem for the desktop. I've tested it with chrome, opera and firefox.

It's a different story on mobile. In fact, I'm only now starting to use webgl because it only recently started working on my phone. So I was pleased by the performance on my Nexus when I packaged this demo up as a cordova application.

After playing around with both Ash and Artemis, I have to say I prefer Artemis. In general it is easier to work with.

In artemis you will declare the aspects for a system, where in ash you define separate node classes. Classes which are like manual boilerplate that I have to maintain and keep in sync with my systems and components.

I also like the 'createEntityFromTemplate' semantics, as well as the 'Blackboard' which I've merged in from the CSharp branch.


Tuesday, September 1, 2015

Trig Lookup Tables

I think that was appendix J of my high school algebra book, and probably the last time I'd thought of them until I looked at this utility class in Artemis-ODB: https://github.com/junkdog/artemis-odb/blob/master/artemis/src/main/java/com/artemis/utils/TrigLUT.java

I realized I might be able to use this in Asteroids. Profiling shows that it calcs sin or cos 50-100 times per frame, and more as the level is increased. So here is my javascript port, which I just include before all the other script tags on the page:

(function () {

    var SIN_BITS = 12;
    var SIN_MASK = ~(-1 << SIN_BITS);
    var SIN_COUNT = SIN_MASK + 1;
    var radFull = (Math.PI * 2.0);
    var radToIndex = SIN_COUNT / radFull;
    var sin = new Array(SIN_COUNT);
    var cos = new Array(SIN_COUNT);

    for (var i = 0; i < SIN_COUNT; i++) {
        sin[i] = Math.sin((i + 0.5) / SIN_COUNT * radFull);
        cos[i] = Math.cos((i + 0.5) / SIN_COUNT * radFull);
    }

    Math.sin = function(rad) {
        return sin[(rad * radToIndex) & SIN_MASK];
    };

    Math.cos = function(rad) {
        return cos[(rad * radToIndex) & SIN_MASK];
    };

})();

Increasing SIN_BITS up to 16 will improve accuracy but increase memory usage. The system sin and cos functions return approximations, so how close do we need to be?

Conventional wisdom (well, stackoverflow anyway) seems to think that there is not much point, it's not really a bottleneck with modern hardware and modern browsers.

And they are correct - I can't really tell a difference in Chrone. At least not on my desktop, but it's a different story on my phone. Here it bumps the frame rate from a steady 29 fps up to 35-45 fps swings. Still not playable, but it show there is plenty of room for performance tuning, especially if I want to include mobile as a target.

Tuesday, August 4, 2015

Hey, you got your Gulp in my Cakefile!

You know the problem. Cake has a lovely command line interface, but no plugins. Gulp is a swiss army knife / bucket of lego's, but you don't get command line parameters.

It sounds like they are made for each other. How can we integrate them?

To start, we can expose our gulpfile by appending this line:

module.exports = gulp;

Then we can access it from our cakefile:

gulp = require('./gulpfile')
...
task 'serve', 'open build/web in browser', ->
  gulp.start('serve')

task 'test', 'open web/ in browser with live reload', ->
  gulp.start('test')

That doesn't really get us much, but we can at least access our 'legacy' script.
It turns out that gulp doesn't need to live in a gulpfile. It can thrive right in our Cakefile:

gulp = require('gulp')
webserver = require('gulp-webserver')

option '-e', '--environment [ENVIRONMENT_NAME]', 'set the environment to open in browser'
task 'serve', 'open in browser', (options) ->
  env = options.environment ? 'rel'

  if env is 'rel'
    files = './build/web'
    liveReload = false
  else
    files = './web'
    liveReload = true

  gulp.src(files).pipe webserver(livereload: liveReload, open:true)


Now I can preview my web page. To view the release version:

$ cake -e rel serve

Or to view the development version:

$ cake serve


Friday, July 17, 2015

A Tale Of Two Constructors

Or - Integrating cocos2d-js inheritance with native coffeescript classes. Nah, that just sounds boring.

Here is the thing. Many existing script modules use a simple inheritance model much like the one described by John Resig. That being the case, I can simply extend framework classes using coffeescript's extend keyword:

class Game extends Phaser.State

class Scores extends Backbone.Model

This works because coffeescript uses the same basic model. But try that with cocos2s-js:

class Game extends cc.Layer

Sure, it will compile. But when I run the app, I just see a black screen, and there are no errors showing up in the console. This is because Cocos-js uses a different inheritance model, with it's own constructor and super methods. Instead of extending your object with a superclass, cocos requires you to pass in a prototype object that is used as a mixin to dynamically build a new class:

klass = cc.Layer.extend(Game::)

You can also use a new Game object instead of the prototype. I use a factory method:

class Game
  @create:() -> new (cc.Layer.extend(new Game()))

and then I have to do is remember to call Game.create() instead of new Game()

So where are the 2 constructors? You said there would be 2 constructors.

Suppose we have this class to define the main menu:

class Menu

  @create: (args...) => new (cc.Layer.extend(new @(args...)))

  user: ''
  debug: false

  constructor: (options) ->
    @user = options.user
    @debug = options.debug

  ctor: ->
    @_super()
    quitNormal = new cc.Sprite(res.quit_png, cc.rect(0, 0, 64, 64))
    quitSelected = new cc.Sprite(res.quit_png, cc.rect(64, 0, 64, 64))
    quitDisabled = new cc.Sprite(res.quit_png, cc.rect(128, 0, 64, 64))
    quit = new cc.MenuItemSprite(quitNormal, quitSelected, quitDisabled, @onQuit)
    quitMenu = new cc.Menu(quit)
    {width, height} = cc.director.getWinSize()
    backMenu.setPosition(cc.p(width - 40, height - 10))
    @addChild(backMenu)
    true

  onQuit: =>
    cc.log 'Bye'


Then we invoke it in a scene.

  scene = new cc.Scene()
  scene.addChild(Menu.create(debug:true, user:'Norville Rogers'))
  cc.director.runScene(scene)


  • The first, native constructor is called by new @(args...). 
  • The second constructor, 'ctor' gets called later by new (cc.Layer.extend())


cc.log('Name:', level.name)

Prints to the console:

 Name: Norville Rogers

Tuesday, July 14, 2015

Visual Studio Code for Linux

Code: A Visual Studio for Linux.  Now I understand how Alice must have felt in Wonderland.

Code is a preview with only 2 releases under it's belt. And it's quickly becoming my favorite javascript editor. It's blazingly fast. I hate slow code editors. And it has Intellisense! The biggest thing missing is a quick way to preview my web page. But I can work around that:
  1. $ cd MyProject
  2. $ npm install --save-dev superstatic
  3. $ npm install --save-dev open
  4. Edit the file .settings/launch.json. If this file doesn't exist, hit F5, and a new template will be created.
  5. Change "program": "main.js" to "program": "bin/server.js",
  6. Then create bin folder and the file bin/server.js (code below)
Now, when you hit the F5 key, you can preview your web page in your default browser. This works for me on both Linux Mint and Windows 7.

Assuming that my project has a web/index.html as the main page:

/**
 * Run a static server
 */
var server = require('superstatic').server;
var open = require('open');
var path = require('path');

var options = {
 port: 3474,
 host: 'localhost',
 config: {
  root: './web',
  routes: {
   '/': 'index.html'
  }
 },
 cwd: path.resolve(__dirname, '..'),
 debug: false 
};

server(options).listen(function(err) {
 open('http://localhost:3474');
});

Tuesday, May 12, 2015

Hapi with Memcached on OpenShift?

Not really? Me too.

I couldn't get catbox-memcached to work. No matter what I tried, all I was getting was a 503 Gateway error. Which means my server wasn't connecting to the memcached server.

Eventually, I follow the adage from Sherlock Holmes - when you have eliminated the impossible, whatever remains, however improbable, must be the truth. In this case, it seemed improbable that the correct password wouldn't work.

So it doesn't accept passwords???

And sure enough, that is the case. The underlying component, memcached, doesn't support passwords - https://github.com/3rd-Eden/node-memcached/issues/219.

This may not be an issue for self-hosting, but in my case, OpenShift only gives me an authenticated option. But there is another component that does support a password protected connection - MemJS. I've made a copy of catbox-memcached, named catbox-memjs, which wraps the memjs cache component. It's available here on https://github.com/darkoverlordofdata/catbox-memjs and on npm.

Friday, April 24, 2015

Modular MVC using LoopBack/Express

Express is pretty simple to use, and simplicity comes at a price. For me, that price is organization. All the views are in one big folder, as are public assets. I prefer a modular organization, and reading this post (https://strongloop.com/strongblog/bypassing-express-view-rendering-for-speed-and-modularity/) pointed out that the key is that the rendering engine breaks modularity.

So I created a top level folder named application, and moved the views out of the server folder, and static content out of clent:

project
| -- application                modules
|     | -- index.coffee  module bootstrap
|     | -- modules.json  module config
|     + -- user          
|           | -- client/public
|           | -- server/boot
|           | -- server/views
|     + -- game          
|           | -- client/public
|           | -- server/boot
|           | -- server/views
| -- client                     not used
| -- common/modules   unchanged
| -- server                     removed views
| -- .bowerrc                   the usual
| -- .gitignore                 ditto

In the main server/server.coffee, after the standard boot:

boot app, __dirname
...
modules = require('../application')
modules app

This runs application/index.coffee, which boots each module, based on the config:
./modules.json:

{
  "user": true,
  "game": true
}

./index.coffee:
fs = require('fs')
path = require('path')
loopback = require("loopback")

module.exports = (app) ->

  for name, enabled of require('./modules.json')

    # -- Boot the module scripts  --
    if enabled
      do (name) ->  # closure on name value
        mod = {}    # and for communication within module

        for filename in fs.readdirSync(path.join(__dirname, name, 'server/boot'))
          if path.extname(filename) in ['.coffee','.js']
            boot = require(path.join(__dirname, name, 'server/boot', filename))
            boot(app, mod)

    # -- Mount static files --
    app.use loopback.static(path.join(__dirname, name, 'client/public'))


All of the content is created from each applications server/view and client/public folders.
Each application has it's own server/boot folder, where I put controllers and rendering engine.
And if I do it right, I can drop my used module into another project and be good to go.

An extra benefit - my user module uses jade templating, while my game module is using liquid templating. Why would you want more than 1 templating engine? Well, I'm lazy. My user module is essentially the loopback-example-passport github repo that I'm tweaking a bit. All of their views use jade. But, I prefer using liquid for my own development.

The full project (wip) is over here - https://github.com/darkoverlordofdata/games. 

Friday, April 17, 2015

Using View Layouts in CodeIgniter

I'll show you how tp extend CodeIgniter's loader to enable layout views.

CodeIgniter doesn't use a template engine. I think their argument that PHP is already a templating language is acceptable for small projects - my team is just me, templates would just add to project complexity and maybe impact performance.

But I do miss the concept of layouts. Instead, codeigniter uses this idiom:

    $this->load->view('templates/header', $data);
    $this->load->view('pages/'.$page, $data);
    $this->load->view('templates/footer', $data);

That's ugly. As your site grows, and you need to sync css to javascript libraries between headers and footers, this results in maintenance pains. I'd prefer to embed my content in a layout:

  <html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h1>Hey!</h1>
        <div class="content">
        <?php echo $content; ?>
        </div>
        <hr />
        <em>© 2014</em>
    </body>
</html>

And then invoke like this ...

    $this->load->setLayout('layouts/main');
    $this->load->view('pages/'.$page, $data);


Well, it's pretty simple to extend CodeIgniter to do this by customizing the view load behavior. First, we'll create the class ./application/core/MY_Loader.php (MY_ is our customization namespace), and add a couple member variables:

    class MY_Loader extends CI_Loader {

        var $layout = '';
        const EXT = '.phtml';

    }

The $this->layout variable holds the file path to the layout. I am also using a different file extension for my views. This keeps me mindful not to burden my views with too much logic. It's too easy to get mixed up when with the views and code have the same file extension.

 Now the constructor:

    function __construct() {
        parent::__construct();
        
        $layout = config_item('layout');
        if ($layout <> '') {
            $this->layout = $layout.self::EXT;
        }
    }    

Make sure to call the core class constructor, and fetch a default layout value from the site configuration (we'll see how to add that below). We'll add a convenience method to set the layout manually:

    function setLayout($layout) {
        $this->layout = $layout.self::EXT;
    }

And finally, we override the view method of loader:

    function view($view = '' , $view_data = array(), $return = FALSE) {  
        if ($view <> '') {
            $view = $view.self::EXT;
        }
        if ($this->layout <> '') {
            $view_data['content'] = parent::view($view, $view_data, TRUE);
            return parent::view($this->layout, $view_data, $return);
        } else {
            return parent::view($view, $view_data, $return);
        }
    }

If there is no layout, we use the standard process. Otherwise, we first merge the view and data to create partial content, and them inject that into the layout.

Remember the configuration? We add the following line to the end of ./application/config/config.php:

$config['layout'] = 'layouts/default';

Of course, we also have to create our default layout: views/layouts/default.phtml - I'll leave that up to you.

 You can find more about extending codeigniter at http://www.codeigniter.com/user_guide/general/core_classes.html

Monday, April 13, 2015

CodeIgniter Is Back!

CodeIgniter just released version 3.0 a couple of weeks ago. I was sad to see EllisLab pull support, but it's been picked up by British Columbia Institute of Technology

Hooray! CodeIgniter is my go to php framework. To celebrate, I installed it to OpenShift. To facilitate this, I've forked a copy of the CodeIgniterQuickStart , updating it for 3.0.0

I've also moved assets and index.php to a public folder, which OpenShift accepts as the DocumentRoot. This simplifies asset management  - style sheets are now in css, not in assets/css. Plus, the php code isn't as exposed.

To use this quickstart, select Add Application from the OpenShift console, and select a CodeIgniter 2 application. Then, enter this repository url into the Source Code field: https://github.com/darkoverlordofdata/CodeIgniterQuickStart, and click Create Application.


Sunday, April 12, 2015

Using Ash with Phaser

The coffeescript port of Ash now works as a Phaser plugin.  To show you how it works, I've taken the old standby Making your first Phaser game and converted it to use Ash.

We start out pretty much like any phaser game, with one exception - you'll note that I haven't given phaser an update function:

    @game = new Phaser.Game(@width * @scale, @height * @scale, Phaser.CANVAS, '',
      init: @init, preload: @preload, create: @create)


Our init and preload are also no different:

  init: =>
    @game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL
    @game.scale.minWidth = @width * @scale
    @game.scale.minHeight = @height * @scale
    @game.scale.maxWidth = @width * @scale
    @game.scale.maxHeight = @height * @scale
    @game.scale.pageAlignVertically = true
    @game.scale.pageAlignHorizontally = true
    return

  preload: =>
    @game.load.image 'sky', 'assets/sky.png'
    @game.load.image 'ground', 'assets/platform.png'
    @game.load.image 'star', 'assets/star.png'
    @game.load.spritesheet 'dude', 'assets/dude.png', 32, 48
    return

Things change once we get to create.

  create: =>

    game = @game

    @stars = game.add.group()
    @platforms = game.add.group()
    @scoreListener = new Phaser.Signal()
    @cursors = game.input.keyboard.createCursorKeys()

    @ash = game.plugins.add(ash.ext.PhaserPlugin, Nodes, Components)


The Ash plugin take 2 parameters: Nodes and Components - these are simply hashed lists. A components are simple classes, for example the Collision component:

Collision: class Collision
    a       : null
    b       : null
    constructor: (@a, @b) ->

While nodes are simply property lists

Nodes = do ->
  CollisionNode: class CollisionNode
    collision : Components.Collision
  CollectorNode: class CollectorNode
    collector : Components.Collector
  PlayerNode: class PlayerNode
    player    : Components.Player

After initializing the ash plugin, we create our entities and start our systems. It's these systems that take the place of the update function:

    @createBackground('sky')
    @createGround('ground')
    @createLedge('ground', 400, 400)
    @createLedge('ground', -150, 250)
    @createStars('star', 70, 0, 12, 10)
    @createPlayer('dude', 150, 350)
    @createScore(16, 16, 'score: 0', fontSize: '32px', fill: '#000')

    @ash.addSystem(new CollisionSystem(this), SYSTEM_RESOLVE_COLLISIONS)
    @ash.addSystem(new PlayerMovementSystem(this), SYSTEM_MOVE)
    @ash.addSystem(new CollectorSystem(this), SYSTEM_UPDATE)
    return


When creating the entity, I use a parallel construction, building the phaser game object alongside the ash entity:

createBackground: (key) ->

    # phaser sprite
    sprite = @game.add.sprite(0, 0, key)
    @game.world.sendToBack(sprite)
    @game.physics.enable(sprite, PHYSICS_TO_USE)

    # ash entity
    sky = new ash.core.Entity('sky').add(sprite)
    @ash.addEntity(sky)
    return


You can get all the code needed for this demo at https://gist.github.com/darkoverlordofdata/eb26c00c6c2bf05da1ba

It's also include as the example program for my phaser game controller plugin.



Friday, April 3, 2015

Getting the Physics Step Right

After porting the Ash framework to coffeescript it seemed to me the next logical step was to use Box2d to calculate the asteroid movement. This actually made the game fun - now the asteroids bounce off each other, and stuff...

But performance on android suffered. Especially in the Cocoon Canvas+ environment, which puzzled me because I'm using the native Box2d plugin. Until I found this excellent post from Allan Bishop, which explained very well what I was running into.

I had been naively calling world.Step() from my game loop, which is driven by requestAnimationFrame. This works ok in the chrome desktop browser, until there is a performance load, and not ok at all in chrome for android. The problem is, when performance suffers, the frame rate starts to slip, resulting in the 'jiggly' physics I was seeing. There are a couple of ways to work with this:

  • Fixed Time Step
  • Interpolate the time delta to sync with the frame rate

So, splitting my PhysicsSystem into two classes, I implemented both. 

One, FixedPhysicsSystem, uses setInterval to cause world.Step() to be called every 1/60 seconds. 
The other, the SmoothPhysicsSystem - implements Allan's ActionScript example.

As it turns out, I need both.  When using the Cocoon Box2d plugin, using an absolute value of 1/60 to advance the physics works well, but interpolation makes it worse. I found the opposite to be true in the browser. So I check to see if the plugin is present, and use the appropriate physics system class.

Friday, March 6, 2015

CocoonJS and the Quest for More Power

Games demand performance, and as cool as Cordova is, games can hit the performace wall. So I was very interested in Ludei's CocoonJS Canvas+ environment. The Box2D demo is impressive. But I was unable to get other Box2D demo's to run. In fact, I've just recently gotten a project to run in Canvas+. Based on a port of the Ash Asteroid demo, my version is in coffeescript. 

What I find is that you need to design for the environment from the ground up. Approach this like a cross browser project with a new browser type:

  • Check navigator.isCocoonJS to see if you're in the browser or cocoon.
  • There is no html document. All body tags except script are ignored.
  • You must use document.createElement('screencanvas') to access Canvas+
  • If you need other elements, like buttons, you need to use Cocoon.App.Webview
  • Canvas+ does not implement a complete Box2D API. Depending on your reference version, less then half the api is available.
That last item was really the biggest issue. For example, there is no world.GetBodyList(), no body.GetNext(). SetDebugDraw() does nothing.  You can infer from this that there a virtualy no existing Box2D demo's out there that will work in the environment.

So how do you get Box2D working in Cocoon? 
  1. All objects must be able to draw themselves
  2. Keep explicit references to all your bodies.
  3. Check the source and make sure the object/method you need actually exists.

My asteroids game does not yet accept touch input. So all I can do now is watch the asteroids bump off each other, and explode my ship if they happen to bump it. You know, I never thought that would be so exciting :)

Friday, February 20, 2015

Haxe vs Dart

I've had my blinders on for the past couple of months, while I've been working on my first game, AlienZone.
A major part of my project was finding the right technology stack. My three main requirements are:

1) I do all my development on Linux
2) My primary target is Android
3) I want run the same code on a website.

My first try was to use Cordova, CoffeeScript, and Phaser. This soon ran into challanges. Organizing your javascript code is full of pitfalls, even when using node and browserify. But a bigger problem was that classical object hierarchies are just too brittle for games. And load time sucked.

Research pointed me in the direction of entity component systems progamming to solve the inheritance problems, Dart to addresses code organization, and CocoonJS for better performance. My stack became Cocoon, Dart, Play_Phaser and Dartemis. This works quite well,  and you can play this version at http://darkoverlordofdata.com/alienzone-dart/


But I still had long load times with my native Android app. I found I didn't want to play a game that takes too long to load. So I looked around and found another option, Haxe. I decided on HaxeFlixel and Ash. I found HaxeFlixel to be similar to Phaser, and Ash similar to Artemis. Enough so that it only took 2 weeks to port my code while learning Haxe. I'm satisfied with the native performance of this version. The html5 target is not quite as nice, but it's a secondary target. You can play this version of the game at http://darkoverlordofdata.com/alienzone-haxe/.


The code for Alien Zone is open source GPL3, and both versions are available at
https://github.com/darkoverlordofdata/alienzone-dart
https://github.com/darkoverlordofdata/alienzone-haxe

I've decided to go forward with the Haxe version, only because my primary target is Android. If I was to target HTML, I'd definitely use Phaser, I think it just looks prettier, and has better response. The HaxeFlixel html5 target is still experimental, so that may improve, especially if they decide to use phaser for a front end.

Monday, January 12, 2015

A Poor Man's jQuery

Ok, so jQuery isn't exactly expensive - in fact it's free and open source.

But browser's have become more standardized,. New frameworks that don't depend on jQuery - polymer, angularjs, phaser.io - are becoming more common. I find that I seldom need to install jQuery these days.

But I find myself missing the $('something') syntax. Instead, I'm typing document.querySelector all over the place:

document.querySelector('paper-tabs').addEventListener('core-select', function() {
  document.querySelector('core-pages').selected = document.querySelector('paper-tabs').selected;
});

This is much clearer:

$('paper-tabs').addEventListener('core-select', function() {
  $('core-pages').selected = $('paper-tabs').selected;
});


It seems overkill to install jQuery just to get the querySelector shortcut. But I can't just say:

var $ = document.querySelector;

I will get an error that the null object doesn't have a method named 'querySelector'.  This simple assignment in effect unbinds the method from it's 'this' reference. Instead we need to do this:

var $ = document.querySelector.bind(document)

Now, the 'this' reference still points to document, so that this will work:

(function($){

  $('paper-tabs').addEventListener('core-select', function() {
    $('core-pages').selected = $('paper-tabs').selected;
  });

})(document.querySelector.bind(document));