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.