Performance Considerations - micojs/micojs.github.io GitHub Wiki

Switches and Game States

In C games it is common to have a switch to decide what to do depending on a game's state:

int state = MenuState;

void updateMenuState() {
  state = GameState;
}

void upate() {
  switch (state) {
  case MenuState: updateMenuState(); break;
  case GameState: updateGameState(); break;
  case GameOverState: updateGameOverState(); break;
  }
}

In C this gets reduced into a simple jump table and is relatively cheap.

In JavaScript, switches aren't limited to just int values. This means that, by default, they'll turn into a series of if-else checks, possibly doing type conversions and string comparisons.

The best implementation in JavaScript is to do away with the switch entirely. Not only is it faster, it consumes far less space in both Flash and RAM. It is also easier to type and less error-prone.

let state = updateMenuState;

function updateMenuState() {
  state = updateGameState;
}

function update() {
  state();
}

Object-Oriented Programming

The compiler currently optimizes accessing properties using this. It is better to use this.x multiple times throughout a function than to copy it into a local variable.

However, accessing other objects' properties is not optimized.

Instead of something like this:

for (let i = 0; i < 10; ++i) {
  if (bobs[i]) {
    bobs[i].something();
    bobs[i].otherthing();
  }
}

It is better to use a temporary variable:

for (let i = 0; i < 10; ++i) {
  const bob = bobs[i];
  if (bob) {
    bob.something();
    bob.otherthing();
  }
}

Graphics Engine

Command Lists

In order to be able to display full-resolution 256-color graphics on devices that don't have enough memory, MicoJS does not use a framebuffer. Instead, it has a list of drawing commands, which it executes after the game's render function is called, streaming the resulting data directly to the screen.

This has a few important implications.

  • since each text/rect/image call adds a command to the list, it is better to have fewer but larger commands (think concatenating your strings together and calling text once) than multiple smaller ones (calling text multiple times).

  • This is the reason why there isn't a pixel function. Not only would it be uselessly slow, it would likely run out of memory easily.

setPen

When called with three arguments, the setPen function searches the palette for the closest color to the one provided. It is much faster to cache the resulting color's index:

// slow
function render() {
  setPen(0, 0, 0);
  clear();
}

// faster
const black = setPen(0, 0, 0);
function render() {
  setPen(black);
  clear();
}