Wednesday, June 17, 2015

html5 - Capitalizing on JavaScript's prototypal inheritance



JavaScript has a class-free object system in which objects inherit properties directly from other objects. This is really powerful, but it is unfamiliar to classically trained programmers. If you attempt to apply classical design patterns directly to JavaScript, you will be frustrated. But if you learn to work with JavaScript's prototypal nature, your efforts will be rewarded.
...
It is Lisp in C's clothing.


-Douglas Crockford



What does this mean for a game developer working with canvas and HTML5? I've been looking over this question on useful design patterns in gaming, but prototypal inheritance is very different than classical inheritance, and there are surely differences in the best way to apply some of these common patterns.


For example, classical inheritance allows us to create a moveableEntity class, and extend that with any classes that move in our game world (player, monster, bullet, etc.). Sure, you can strongarm JavaScript to work that way, but in doing so, you are kind of fighting against its nature. Is there a better approach to this sort of problem when we have prototypal inheritance at our fingertips?




Answer



To get decent performance out of JavaScript with modern JS engines one needs to write code that mirrors common structural typing or duck typing patterns. Structural typing is more powerful than providing types only by inheritance but does not really change the design patterns used by games.


As an example, in C++ or Java, where one usually types by inheritance, one usually has deep type hierarchies with several interfaces / virtual classes in order to implement MVC. But games shy away from this kind of design pattern already because it doesn't really help model the kind of data games deal with.


The patterns one does find most useful in game design, like context objects, components, flyweight, or strategy, do not tend to use complicated inheritance hierarchies in the first place, even when implemented in languages like C++. Components involve a single virtual class (at most). Flyweight usually uses C++'s (awkward) structural typing via templates. Strategy often uses some form of type erasure for performance or programmer sanity.


The one exception to this is the prototype pattern itself, which is often found in some form in games, especially for designer-driven data. Using JavaScript makes this pattern trivial. But it is not a particularly difficult pattern to implement, at least poorly, in any language that supports associative data structures. Using JS would let you use it more because you can leverage the underlying engine's optimizer. But I'm not sure if that would really change the way one programs - a naive prototype pattern is already in plenty of places in plenty of games despite its often poor performance.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...