Monday, November 23, 2015

Racing Cars

Asphalt 8: Airborne is an amazing racing game for Android devices. I regularly run my battery from full to empty playing it. It is not what one could call a realistic game, what with surviving 200-foot drops and being able steer while in mid-air, but it is fun. And frustrating. The game decides sometimes that you belong in 3rd place. Or last place. Or first place. It is not up to your skill. The game has spoken. But over the longer term, these tend to balance out.

How the game works is, there are a vast number of cars available. Each one has its own characteristics, and you can buy upgrades to them. You win credits for winning races and performing tricks (like barrel rolls and knocking other cars down). There are races against computer-controlled cars, and multiplayer races, where you are pitted against other people online. Kind of amazing what they can do with mobile apps these days.

Each car has a rating according to its characteristics and how much you've upgraded it. You might think that equally-rated cars would tend to perform about equally, but that is not true. There are cars that are simply better for multiplayer racing. Also, I've found that (counterintuitively), the more you upgrade a car, the less well it does against similar rated cars.

The best cars for multiplayer are: Survolt, Felino cB7, and Biome. If you pay attention to who wins races, it's very often one of these. Don't bother with the Corvette or Countache, they just lose. Some others like the Pagani Zonda are fun to drive, and they at least have a chance of doing well in a race, but for dependable top-3 finishes, pick a Survolt, Felino, or Biome, preferably not fully upgraded. Get one and start winning races. That's how you make money.

There will always be more cars and upgrades than you can afford. It takes a lot of racing to win money, but there are a few shortcuts. First, winning streaks: if you place top-3 for 7 races in a row, you will sometimes win a class-D engine upgrade. Be aware of what your most expensive upgrade available is. When you win the upgrade, that can save you a lot. Similarly, if you continue on to get 9 in a row, you can (sometimes) get a class-C. Again, they can be worth a lot of money.

A relatively recent development, the Mastery series of races, also has a few upgrades scattered among the prizes. You don't have to claim them immediately upon winning them. You can look through your inventory and see where it would best be applied.

Another way to save a few bucks is to watch for cars to go on sale. They can be anywhere from 20-50% off.

There's also a bonus for your first race of the day, if you play every day. Double your money. Try to do a race that promises a good payout: one where there are stars to be won. If the race isn't going your way, you can quit the race and re-start, and you'll still have the bonus waiting for you.

There are always "special events" going on, too. These are time-limited, running for 1 to 5 days, and your participation is also limited by "fuel bars" that you have that recharge over time. The money payoffs are fair, but the non-money prizes are what usually make them worthwhile. In addition to earning prizes for scoring 1st place or beating a time, there's a hierarchy of prizes for the top scorers overall. In a multiplayer cup, that means playing again and again, which is usually not worth it. But in a non-multiplayer event, you just need to manage your best race.

Another aspect of the game is "Pro Kits". These are upgrades that can take you beyond the maximum normal upgrades, but in addition to money, you have to have cards specific to the upgrade. Those cards are often prizes in the special events. Although the intent is for the pro kits to be applied after you've maxed a car's upgrades, you can apply them at any time. This is good if your stash has gotten too full for you to open more boxes of cards. However, you need to be judicious about your card use, because you will run out of cards for particular upgrades. So focus on upgrading one or two cars in each class, rather than just applying upgrades all over the place.

Got tips? Tell me in the comments.

Sunday, September 20, 2015

Understanding Knockout

What's the Goal?

I once worked with a man who, when discussions of a solution turned confusing, would always ask, "What's the goal?" It is surprising how often we see a problem and try to find a solution without really understanding what solving the problem really means. The problem that we had in AJAX apps is that our data was stored in the DOM, and we would always be fiddling with sometimes-complicated widgets there to do conceptually simple things. And the entanglement meant that changing superficial presentation things might require wide-ranging changes to the code.

The goal, then, is to separate presentation (the view) from data (the model). Numerous libraries exist to solve this problem, but most of them threw in several other goals, leading to over structured and indirect solutions to the problem. Knockout focuses on this one goal, and as a result is easy to learn and easy to read.

The Knockout Approach


Knockout says that there are two types of JavaScript in an application: the ViewModel and the Bindings. The Bindings exist to synchronize the ViewModel and the View: changes in the View that are made by the User will be reflected in the ViewModel, and changes in the ViewModel will be reflected in the View.

Because Knockout guarantees the View and the ViewModel will always be synchronized, there is never any reason for you to reach around the Bindings and manipulate the View. That means you're never going to use a jQuery selector outside of a binding. If you are selecting elements of the DOM, stop and ask yourself why you are not dealing with the corresponding element of the ViewModel.

What's a ViewModel?

The ViewModel is a collection of variables that represent everything that can change in the View. Instead of manipulating DOM elements, you manipulate the variables, and the Bindings update the DOM for you automatically. And if the User changes some setting in the DOM, the Bindings update your variables for you.

What's a Binding?

A Binding (or binding handler) is the code that understands how an element of the View should reflect (and be reflected by) ViewModel variables. Knockout comes equipped with a number of the most common types, but you should expect that you will need others to handle specialized widgets. Happily, bindings for many well-known widgets have been written and are available on GitHub (and elsewhere). Still, you should expect that you will need to write some of your own. It is no more difficult than writing DOM manipulation code that isn't part of a binding. Knockmeout has a great writeup on writing custom binding handlers.

Where's the Model?

Some people have (rightly) noted that, although Knockout is billed as an MVVM (Model-View-ViewModel) system, it's not obvious where the Model part is. You model the application you are building with your ViewModel. Any data you work with is part of that, but does not necessarily require being separated from the rest of the ViewModel. That is up to you. Always ask yourself, "What's the goal?"

Friday, May 1, 2015

Class-free object-oriented programming in Javascript

Douglas Crockford has given another talk on the future of Javascript, with particular attention to what he now considers the Right Way to do object-oriented programming, which is quite a departure from classical thought. Years ago, he stopped using new explicitly, and came up with Object.create to use instead, for more straightforward use of Javascript's prototypal inheritance design.

Now, he has also stopped using this, which means he has effectively abandoned Javascript's notion of inheritance altogether. He calls his new style "class-free object-oriented programming", the basic feature of which is that every object actually contains its own methods, rather than sharing them in a prototype or parent object. This is "inefficient" by some measure, but if you think about it, the sharing of methods is simply an optimization, and in most cases, optimizing for space in JS is not going to make a critical difference.

It happens that this was the style I adopted when I got into programming JS, because I was not trained up in classical object-oriented languages. Ironically, more recently, I did get into the typical use of new and prototypes, but I'm going to reconsider that for a while.

Crockford's basic boilerplate for a constructor is:
function constructor(spec) {
  let {member} = spec,
      {other}  = other_constructor(spec),
      method   = function () {
        // accesses member, other, method, spec
      };

  return Object.freeze({
      method,
      other,
  });
}
Which is to say that there is no built-in inheritance; objects that are composed-in are simply member sub-objects. You can, of course, make pass-through member calls.

Danny Fritz blogged about the concept of class-free OO programming, with some helpful illustrative examples, but his techniques differ somewhat from Crockford's, notably in the use of this. Predictably, I have a take that is somewhat different from each of them, but which I think marries their best features.

Crockford uses constructors for everything, which has the code smell of boilerplate in the form of the return Object.freeze portion. Fritz has constructors and extenders, with a copy-in extend function. I have always hated such extenders, and I don't see a reason to have a distinction between constructors and extenders.

Instead, I propose that the proper separation of duties is to have a universal constructor and everything else is an initializer. This gives you freedom to inherit and allows you to avoid the security hazards of this.

The universal constructor looks like this:
Function.prototype.construct = function (spec) {
    var obj = {};
    this(obj, spec);
    return Object.freeze(obj);
}     
Almost too simple to bother with, but it takes care of the boilerplate issue. Note: I formerly had defined this as Object.construct, but this definition makes every function be a potential constructor, which seemed more appropriate.

Now, for any object type (or extension type), all you have to concern yourself with is the initialization. I will illustrate using Fritz's examples of alligator, duck, and goat objects that are defined in terms of extensions Animal, Walking, Swimming, Flying. This is a straightforward port of his alligator:
function alligator (self, spec) {
    self.name = 'alligator';
    self.word = 'grrr';
    animal(self);
    walking(self);
    swimming(self);
}
All of the extensions are just initializers called on the self object (which, being passed in, avoids the security problems of this), and the alligator function is, itself, just an initializer. spec is not used in this case, but I have kept it to show how Crockford's model fits. Most objects do have inputs to their initialization. Similarly, animal et. al. would normally take a second argument.

To create an instance:
var myAlligator = alligator.construct(spec);
It should be clear from this how duck and goat would similarly be created, but let's take a look at the extensions. Again, a straightforward port of animal:
function animal(self) {
    self.name = 'name';
    self.word = 'word';
    self.talk = function () {
        console.log(self.name + ' says ' + self.word);
    }
};
It becomes clear at this point that all the things that inherit from animal have a name and a word. Initialization of those should be done with a spec, rather than having placeholder defaults and each derived object having to know about them:
function animal(self, spec) {
    self.name = spec.name;
    self.word = spec.word;
    self.talk = function () {
        console.log(self.name + ' says ' + self.word);
    }
};
Now we can rewrite alligator:
function alligator (self, spec) {
    animal(self, spec);
    walking(self);
    swimming(self);
}
alligator.construct({name: 'alligator', word: 'grrr'});
So our alligator doesn't merely contain animal, walking, and swimming objects (as would be the case in the Crockford model), but it has been initialized to have those traits directly. This requires that all the traits play nicely with each other. If that can't be guaranteed, Crockford's model offers more security, and can obviously be implemented with pass-through methods like so:
function alligator (self, spec) {
    animal(self, spec);
    var walkTrait = walking.construct();    var swimTrait = swimming.construct();    self.walk = walkTrait.walk;
    self.swim = swimTrait.swim;
}
alligator.construct({name: 'alligator', word: 'grrr'});
Note that I have initialized the alligator self as an animal, then added the other features as traits. Whether you initialize on the object itself or create sub-objects is up to you.

Monday, February 2, 2015

Exploring the smell of Javascript inheritance

In Javascript, objects inherit from other objects. By convention, the objects that are inherited from (prototypes) contain methods, while the inheriting objects contain data. This makes sense, as it is practical to share methods, but each instance must have its own data.
Given that we are interested in (only) the methods of the parent object, it strikes me as something of a code smell that inheritance is done by taking an instance of an object - including, in particular, its data members - to use as a new prototype to which we add functions. It's convenient, it's relatively low cost (what are a few unused variables, for a whole class), but you're still creating things that you will never use. For example, say we have this class:
function Button (label, position) {
  this.label = label;
  this.position = position;
}
Button.prototype = {
  // Button functions
  ...
};
You might derive a new subclass like so:
function RoundButton(size, label, position) {
  Button.call(this, label, position);
  this.size = size;
}
RoundButton.prototype = new Button();
RoundButton.prototype.newMethod = function () {
  // additional functions
  ...
};
You only create the new Button instance so you can inherit from its prototype and add methods to it. The data members don't matter at all to the prototype; you want them in the instance (hence the Button.call).
You could have the Button constructor check to see whether it receives any arguments, and if not, it doesn't create its members. That makes Button responsible for two things: constructing new buttons and constructing new prototypes for derived classes. Another approach would be to separate the prototype responsibility into another class:
function DerivedButton() {}
DerivedButton.prototype = Button.prototype;
Then RoundButton.prototype would be declared:
RoundButton.prototype = new DerivedButton();
Interestingly, because DerivedButton and Button share a prototype, deriving RoundButton from DerivedButton will make RoundButton instanceof Button yield true.
It looks like Object.create was set up to have prototypes inherit through prototypes and not through object instances (as well as to facilitate more traditional object-oriented features).