Array#minimum and Array#maximum

Time for the next installment in 256 JS Game Extensions. It’s been a while hasn’t it? Well don’t worry because here are four new crazy cool additions to the Array class. This brings us up to 40!

Array::maxima = (valueFunction=Function.identity) ->
  @inject([-Infinity, []], (memo, item) ->
    value = valueFunction(item)
    [maxValue, maxItems] = memo
 
    if value > maxValue
      [value, [item]]
    else if value is maxValue
      [value, maxItems.concat(item)]
    else
      memo
  ).last()
 
Array::maximum = (valueFunction) ->
  @maxima(valueFunction).first()
 
Array::minima = (valueFunction=Function.identity) ->
  inverseFn = (x) ->
    -valueFunction(x)
 
  @maxima(inverseFn)
 
Array::minimum = (valueFunction) ->
  @minima(valueFunction).first()

Array#maxima is the core of this set, all the other methods are implemented based upon it. maxima returns a list of the elements that have the maximum value for a given value function. The default value function is the identity function which returns the item itself. This will work great for integers or strings: anything that correctly works with the > operator.

The value function can be overridden for example if you want to compute the maximum length word in a list you could pass in (word) -> word.length

The special case maximum delegates to maxima and returns only the first result. Similarly minima delegates to maxima but inverts the value function.

With these methods many problems that seem complex actually become quite a lot simpler by picking a value function and whether you want to maximize it or minimize it.

Red Ice Premortem – Hard Lessons in HTML5

Over the past two years I’ve been developing a multiplayer hockey game in CoffeeScript. What follows is a rough list of some things that I’ve learned.

And let’s be clear, these are all the mistakes I made before I got to the part where I built the game.

JavaScript
CoffeeScript is great as a programming language, but it’s still built on top of JavaScript. JavaScript has a few crippling problems when it comes to reusable libraries, like the lack of a require statement in the language itself. There are many tools that try to address this, falling mostly into two separate groups: compile/build tools and runtime tools.

Since I use CoffeeScript, a compile time tool fits well into my pipeline. For websites, generally I use Sprockets where you can explicitly require other files using special comments:

#= require player
#= require map
#= ...

This is good. Dependencies can be made explicit and you can require files from other files. The disadvantage is that this all happens during build time, so Sprockets itself doesn’t provide any way to require files at runtime. For rapid development some sort of guard script is needed to recompile all your files when any change. In practice this takes less than a second and changes are immediately available when refreshing the page.

Requirejs is an alternative that provides support for requiring additional files at runtime. This approach is great for development, but still requires a compilation step for optimizing distribution.

Either of these approaches work fine and the correct one to choose depends mostly on how well they integrate with the rest of your toolchain.

These problems would be mitigated greatly by a reliable and robust, game development-specific framework similar to Rails. There are many JS web development frameworks. There are even some that fit certain definitions of robust and reliable. I’ve even spent years trying to create one with its own crippling problems, but that’s a tale for another time.

As of yet I haven’t found any that I could recommend, and that’s coming from someone who spent three years building one. The features that I think are essential are:

  • Command line support
  • Packaging for web/download deployment
  • Rapid development environment
  • First-class testing environment
  • Extensions to core JavaScript libraries
  • Additional libraries specific to games
  • Dependency management as good as Bundler

Many people are working on these issues. For each one there are many attempts, but there isn’t yet an opinionated framework that brings them all together in a way that developers can get started with quickly and easily. The biggest problem is that even by choosing the most popular tool for each issue, you rapidly become the only person in the world who has used each of those tools together.

Distribution

HTML games provide a great multi-platform distribution mechanism: a website that players can go to and play the game directly in the browser. For selling a direct download, a zip file with a run.html file is easy to create – it’s pretty much the same as a zip of the website. Linux/Mac/Windows compatibility is practically free, though the major issue would be the player’s choice of browser. If it is extremely important that the game be played in a quality browser, Chrome Portable can be bundled with the game or provided as a separate install step.

Sharing with testers is also easy, just send a zip or link to the page where you’re developing your game. You could even host everything on Github Pages.

Gamepads

Gamepad support is now quite good in Chrome, but needs support from other major browsers. There are native plugins available that will enable all browsers on all platforms to provide equivalent gamepad support, but it’s too much trouble to assume players will install a plugin and too much additional work for developers to implement as well. Maybe if a plugin matched the API more exactly it would mitigate this from a developer perspective, but asking players to install native plugins defeats much of the gains from an HTML experience.

On the bright side, when playing Red Ice using Chrome, the gamepad support is better than most popular indie games. (Binding of Isaac, I’m looking at you!)

Multi Player

In an attempt to alienate all potential players, I originally designed Red Ice to be played 3v3 locally using XBox controllers. As you can see from this chart, number of friends drops rapidly when owning more than three controllers.

Right now Red Ice is 2v2, and that’s probably correct. I do want to do more experimental games with more than four players locally, but with six or more players, screen real estate starts to become an issue.

Using Multiple Cloudfront Domains with Paperclip

In order to speed up asset loading using a CDN is generally regarded as a good idea. It is also recommended to split up requests among separate hostnames to allow the browser to parallelize loading.

Enabling this in Rails with Paperclip is pretty easy, though the documentation isn’t extremely rich.

You’ll want to set the s3_host_alias option to a proc which determines the correct domain alias based on the id of the object the attachment is for.

  has_attached_file :image, S3_OPTS.merge(
    :s3_host_alias => Proc.new {|attachment| "images#{attachment.instance.id % 4}.pixieengine.com" }, 
    :styles => {
      ...
    }
  )

This sends requests to the following hostnames:

images0.pixieengine.com
images1.pixieengine.com
images2.pixieengine.com
images3.pixieengine.com

The best part is that the same image will always have the same hostname. I’ve seen some people suggest randomly choosing a domain, but that reduces caching potential as the same item could be requested from multiple different domains over time.

Capistrano cached copy takes a long time to copy during a deploy

If you’re using Capistrano to deploy your Rails projects it’s common knowledge to use a cached copy to prevent downloading your entire project from git or svn with every deploy.

What I didn’t know was that by default Capistrano copies over the .git directory when deploying. This was causing a 90 second delay in our deploys. Outrageous!

Fortunately the fix is simple, just cram this into your deploy.rb file.

set :copy_exclude, [ '.git' ]

DSLs In CoffeeScript

When programming if something is hard it means that you are not programming at the correct level of abstraction. Remember your ABCs (Always Be Coding-at-the-correct-level-of-abstraction).

What is the correct level of abstraction? The correct level of abstraction is the level that perfectly matches your problem domain. If you are creating an application about painting and geometry then you’ll probably be using points, lines, colors, areas, blending and more. Be sure to use those in your code as well, because doing cross products by hand is for mathletes, not painters.

I recently put this into practice when I was creating the menu screen for Red Ice:

gamestate "Tournament", MapState
gamestate "Versus", MatchSetupState
submenu "Mini-Games",
  minigame "Zamboni Defense"
  minigame "PushOut"
  minigame "Paint"
submenu "Options",
  item "Config", ->

The structure looks like a menu, with submenus being obvious by their indentation. There’s not a lot of extra syntax junk in the trunk. It’s clean an to the point.

I knew that I wanted the menu to be a simple list of strings and functions. I started out by just using object literals, but noticed much redundancy. In the natural process of drying up the code by removing redundancy and naming functions simply I ended up creating a DSL.

The starting point was creating a function called item.

  item = (text, fn) ->
    text: text.toUpperCase()
    action: fn

At that point the menu became a list of items, which was a big improvement, but several of the functions were similar, like opening a submenu or changing game states. So I decided to add more functions whenever anything was duplicated. These new methods were able to build on the item method I had created before, making them simpler as well.

  gamestate = (name, state) ->
    item name, ->
      engine.setState(state())
 
  minigame = (name) ->
    item name, ->
      engine.setState(Minigames[name]())

The submenu was a little more interesting. Because I made it a function, it was easy to automatically add a back button to each submenu just by sticking it in the function. Additionally implementing the back button was very simple by using the functions I had previously defined. One benefit of CoffeeScript is that I was able to use splats to allow any length of arguments to the submenu function, with each argument after the name being an item in the submenu.

  back = item "Back", popSubMenu
 
  submenu = (name, menuOptions...) ->
    item name, ->
      I.menus.push [back].concat(menuOptions)

Making nested submenus is also a breeze, not that you’d want to nest things deeply, but hey good DSLs make everything easy!

submenu "Mini-Games",
  submenu "Survival",
    minigame "Zamboni Defense"
    minigame "Mutant Attack"
    minigame "PushOut"
  submenu "Cooperative",
    minigame "Paint"

The biggest advantage of DSLs, correct abstractions, and higher-level languages, is that their power compounds. This would have been possible in pure JavaScript, but probably such a pain that it wouldn’t have been worth doing. Once you have a solid abstraction you can then build on it further and even combine different components in new and interesting ways.

If all you have is a hammer it’s going to take you a damn long time to build a house.

How to Create a Compass Extension as a RubyGem to Share Sass Mixins

I was searching for how to include sass mixins in Sprockets projects as a gem dependency. There may be some way to do it but I couldn’t figure it out. That’s why I ended up going for a Compass extension, since I use Compass anyway.

Create the compass extension:

compass create pixie_sass --using compass/extension

Remove the templates directory

rm -rf pixie_sass/templates

Create the gem via bundler:

bundle gem pixie_sass

Add compass as a gem dependency:

gem.add_dependency "compass"

Move the stylesheets folder to be within lib.

Register the plugin in lib/pixie_sass.rb


require "compass"

base_directory = File.join(File.dirname(__FILE__))
Compass::Frameworks.register('pixie_sass', :path => base_directory)

Add your sass files and mixins.

Push to github.

Require the gem in your other projects:

gem "pixie_sass", :git => "git://github.com/PixieEngine/pixie_sass"

See the example pixie_sass gem on github.

Weekly Recap of 1 Hour Daily Game Jams

@mdiebolt and I review our daily 1 hour game jams over the past week. Audio levels in games are still too loud.

First 30 Days:

Week ending 04-14-2012:

I find that doing these 1 hour jams every day really helps to focus my game design skills. Who’d have thought that practicing something for at least an hour every day will make you better at it? Now when Ludum Dare rolls around 48 hours will seem like a 2 year dev cycle.

Function#debounce Useful JavaScript Game Extension #36

I got this from Underscore.js.

###*
Calling a debounced function will postpone its execution until after 
wait milliseconds have elapsed since the last time the function was 
invoked. Useful for implementing behavior that should only happen after 
the input has stopped arriving. For example: rendering a preview of a 
Markdown comment, recalculating a layout after the window has stopped 
being resized...
 
lazyLayout = calculateLayout.debounce(300)
$(window).resize(lazyLayout)
 
@name debounce
@methodOf Function#
@returns {Function} The debounced version of this function.
###
Function::debounce = (wait) ->
  timeout = null
  func = this
 
  return ->
    context = this
    args = arguments
 
    later = ->
      timeout = null
      func.apply(context, args)
 
    clearTimeout(timeout)
    timeout = setTimeout(later, wait)

Already I can see an important use for it. In the code editor we copy out the buffer every keyup. This can lead to a bunch of extra work for the browser when typing. Usually it’s not a big deal because the files are generally small, but on larger files it can add up and cause some lagging. When using debounce the editor will only trigger after enough milliseconds have elapsed since the end of new keyup events. This will keep the IDE from lagging on larger files while you are typing.

Another place debounce is useful is in a game that implements a Halo style health regeneration. Every time the player takes damage a debounced startRegen function could be called. That way the regen will only start after enough time without taking damage has elapsed. In the game version it would probably be better to constrain it to ticks of the engine, or engine elapsed time for more accuracy.

I’m always a big fan of Function functions, they are a great way to reduce boilerplate and solve higher-order problems.

Array#pipeline Useful JavaScript Game Extension #35

###*
Pipe the input through each function in the array in turn. For example, if you have
a list of objects you can perform a series of selection, sorting, and other 
processing methods and then receive the processed list. This array must contain 
functions that accept a single input and return the processed input. The output of
the first function is fed to the input of the second and so on until the final
processed output is returned.
 
@name pipeline
@methodOf Array#
 
@param {Object} input The initial input to pass to the first function in the pipeline.
@returns {Object} The result of processing the input by each function in the array.
###
Array::pipeline = (input) ->
  for fn in this
    input = fn(input)
 
  return input

The main use for this is in the PixieEngine cameras module where we need to process the camera transform with a stream of modifiers. This also allows for the game objects list to be z-sorted, filtered to a subset that passes a clip test, or any other arbitrary stream filter.

I think this is probably some sort of fundamental concept of functional programming, but I’m not sure if `pipeline` is the right name. If anyone has historic info on this please let me know.