Draw With Your Face is a game for Google+ Hangouts created by Aaron Meyers and OKFocus. Some of the mechanics will be familiar to players of other drawing games: players take turns trying to get other players to guess a word with a drawing.
As the name suggests, Draw With Your Face adds a new twist: using face tracking, players create their drawings hands-free using just their face! Its fast-paced and funny. And fun!
Draw With Your Face is a part of Google’s Hangouts Hackathon.
In this post I describe our current Hangouts local development environment. It is set up to have multiple views, with JS and CSS loaded dynamically from a configurable hostname.
Last week, Jonathan blogged about how we got around restrictions in the development version of App Engine that keep you from serving over HTTPS on localhost. To save us from having to deploy to App Engine each time, and also to keep from clobbering our App Engine remote, we instead deploy a small bootstrap and publish everything else locally. As Jonathan mentioned, we have gotten used to various Rails naming conventions, so we’ve tried to replicate some of these for our own convenience, as well as break our app apart so we can serve multiple views and edit them separately.
We made a directory for serving HTML views from localhost, which could then be pushed directly into a div with the JQuery convenience function $(“#div”).load(url). We quickly discovered that while App Engine lets you set permissive CORS headers for your APIs, it is impossible to set similar headers for a static_files URL handler (as defined in app.yaml).
The Python instance has some limited access to the filesystem, so instead we built a trivial API to slurp a file and dump it back at the user. Here, another restriction: the Python instance does not have access to any files in a static_files directory. Thus our solution is to make a directory called “views” in the same directory as main.py and serve our static HTML from there, which is sufficient for development.
main.py:
To use this new API, we made a small Javascript bootstrap that waits for the Hangouts API to load, caches the current hostname and view in localStorage, sets up some buttons so we can switch from view to view, binds to an input box (defined in our app.yml) for changing the hostname, and ultimately loads a view into the container.
/assets/javascripts/bootstrap.js:
You may note the “javascripts” and “stylesheets” functions at the end — Each view loads its own javascript dynamically so we can write individual test environments for different features, and relies on a globally-defined serverPath so that content can be loaded in from a particular host. Acceptable values are “production” for your production App Engine server (defined at the top), “localhost” for a code repository local to each individual user, or a bare IP address. As with the current view, the current host is cached in localStorage so these things don’t have to be set with each app reload. There are a few reasons this might be useful — people who do not have the codebase can demo in a hangout with you, features may be iterated in a single hangout without everyone having to pull from git for minor changes, your local hangout may be swapped to run code from production if you rely on the server side, and so on.
Finally, here is a brief test script that incorporates the Hangouts simple example (state changes, AppEngine API test) with Rehab Studio’s ping test (message send & receive).
/views/test.html:
/assets/javascripts/test.js:
At this point, we have moved beyond this multi-page model toward making a more conventional single-page app, but this configuration is still useful while you are in the planning stages of an app, or breaking in those features peculiar to the Hangouts API. The rudiments of game logic can be worked out in one view, stress tests in another, layout and onboarding defined in a third. Furthermore, being able to set the hostname saves you from having to synchronize codebases when pair programming to debug the multi-user components of a hangout.
Jules