occasionally useful ruby, ubuntu, etc

30Oct/110

Sharing session state in Node.js between your HTTP server and websockets server

At first, sharing your session state between your Node.js HTTP server and websockets server might seem difficult. However, if you're using Express and NowJS (or the technologies they're built on, Connect and Socket.IO, respectively), most of the work has already been done for you -- it's just a matter of connecting the right pieces together. An example follows, written in Coffeescript.

30Oct/110

CoffeeScript in Node.js

Here's a couple common development patterns I've come across in Node.JS+CoffeeScript.

Requiring Coffeescripts without compiling

So for the last couple weeks I've been doing Node.js development while using CoffeeScript, but I've been using `coffee -cwb .` in one console (which compiles, watches, and "bare bones"-style on the current directory) while running `node app.js` in another tab. This works okay, but whenever you add a new file you have to restart coffee, and it just seems...noisy. All these extra js files everywhere! Fortunately there's a better way, but it's not really documented.

Before:
require "./my_other_file.js" # compiled from "my_other_file.coffee"

After:
require "coffee-script"
require "./my_other_file"

CoffeeScript registers the .coffee extension automatically. This means no more lingering js files.

Bootstrapping Coffeescripts

Another trick I've discovered applies to times that you have to execute a js file -- `node --debug myapp.js` comes to mind. Well, here you can just make a bootstrap.js file that contains two lines:

require "coffee-script"
require "./myapp"

Now you can `node --debug bootstrap.js` and everything works. Simple stuff.

Loading exports from a module efficiently

Thanks to Coffeescript's destructuring assignments capability, you don't have to write code that looks like this:

MyClass = require("./my_class").MyClass

you can simply write

{MyClass} = require("./my_class")

and it will do the same thing. You can even pull out multiple exports (i.e. {MyClass1,MyClass2}) at a time, though this doesn't come up for me that often.

Conclusion

Hope that was helpful. There are certainly a number of undocumented tricks that you discover when looking at other people's source code :)

p.s. sorry about the lack of source highlighting; don't feel like embedding gists in here. Code is pretty simple anyway!

Filed under: coffeescript No Comments
20Aug/110

Recovering your submitted form data in Chrome

Have you ever submitted form on a website after filling in a lot of text (maybe a comment), only to get an error on the other side? And when you hit back, your nice long response is gone? There's a (sort of easy) way of retrieving it, if you don't stray from the landing page after you submit the form -- at least in Chrome.

1) Wrench icon > Tools > Developer Tools
2) Network tab
3) Click on the network request with the same name as the current page (that matches the URL)
4) Click the Headers tab in the right section of the developer tools
5) Scroll down to the section "Form Data" (you may need to Expand this section by clicking the > arrow)
6) Copy and paste your previous response into somewhere safe (Notepad?) while you attempt to resubmit the form or frame your amazing writing for later.

I'm pretty sure you can do the same thing with Firefox, but it would require you to install Firebug.

Filed under: musing No Comments
20Mar/115

ACID Cloud databases to keep an eye on

So far, "database in the cloud" options have been pretty limited. You have Amazon's SimpleDB, which is slow, eventually consistent, and not really a database except in the loosest sense of the word; there's Amazon RDS, which is a managed MySQL instance and scales up, but not out; and of course you can run database server yourself on any of the cloud servers out there (Amazon EC2, Rackspace, GoGrid, Linode, Slicehost, etc etc). But none of these offer one-click scale out ability, which is really the hardest part of database scaling. However, there are a few options cropping up, most of which are in beta.

Filed under: web 2.0 Continue reading
19Mar/111

Quasi-turn-based game design: movement

I'm fiddling around with building an online browser-based game right now, but am having some trouble trying to figure out how and when different units should move (since they can move at different speeds). The game is turn-based, i.e. actions happen in fixed time intervals, but it has real-time elements, since each unit is on its own clock -- actions that happen every 5 minutes for one unit don't necessarily coincide with actions for another unit that also has a 5-minute tick interval. In my mind, these are the requirements:

  • No unit should move multiple tiles in a single turn -- in a given turn/tick/whatever, they move at most one tile.
  • Some units can move faster than others -- namely, cavalry can move 3x as fast as infantry, for example.
  • Units that have varying movements speeds could have the same attack speed -- just because they move faster, doesn't mean they do everything else faster.
  • The speed of units can change dynamically -- if they are Haste'd by magic spell, or Slow'd by a bog, then...they do what you'd expect.

So far I've come up with three strategies for how one might implement these in a game.

28Feb/111

Ye Olde Key-Value Store: BerkeleyDB

This weekend I explored the possibility of implementing something resembling Redis but on top of an existing, mature database engine.  It's a key-value store, it has transactions, it supports locks and concurrent writes, replication, etc.  While it ultimately didn't end up panning out (trying to get sets to work efficiently just wasn't working out), it was an interesting learning experience for me familiarizing myself with the Java DPL (Direct Persistence Layer) in BerkeleyDB.  (Let that be your warning that there's Java in this post!)

Filed under: java Continue reading
16Jan/110

AutoPull: you push, it pulls

So you use GitHub and some compiled language, but not everyone can or wants to compile the source, they just want the artifacts. I made a tiny app that aids in this sort of thing. If you have ever wanted to execute an event in Ruby in response to a push to a repo via GitHub's Post-Receive URL hooks, this is probably a good starting point.

AutoPull on GitHub.

Additionally, it doesn't have to just be used with GitHub (anything that can automatically hit a URL works), and it doesn't even have to be used for pulling down source -- it can send an email or something. Right now I'm using it for HydrateJS -- when I push some new CoffeeScript to GitHub, it automatically pulls and rebuilds the .js file on my server.

Filed under: ruby No Comments
16Jan/112

HydrateJS: Smarter Javascript Serialization

Finally, here it is: HydrateJS.

It's a library that helps you serialize proper Javascript objects, more than just hash-like objects like JSON.stringify can handle. Anyway, I put a lot of time into the documentation inside the library as well as on the Github Pages link, so check those out! There is also a full suite of specs.

For some of the technical challenges, see my previous post.

Let me know what you think in the comments, and if you're using it, feature requests, etc.

2Jan/113

Javascript Serialization

Note: RSS subscribers, I've (finally) enabled summary-only feed entries, so you will have to click through to see the full post.


Have you ever wanted to serialize entire Javascript objects? When I say objects here, I don't mean the simple hashes that you get by saying {foo: "bar"} -- I mean instances of your User, Product, Query, etc prototypal Javascript instances. JSON.stringify gets you part of the way there, but notice this doesn't work:

function Person(){}
Person.prototype.greet = function(){ alert("Hi!"); };

var p = new Person();

JSON.parse(JSON.stringify(p)).greet(); // throws Object #<an Object> has no method 'greet' in Chrome
view raw 1_greet.js This Gist brought to you by GitHub.
var a = {"foo": "bar"};
var b = [a, a];
b[0] == b[1] // true
var c = JSON.parse(JSON.stringify(b));
c[0] == c[1] // false
// Step 1: setup
function Person(){}
Person.prototype.greet = function(){ alert("Hi!"); };

var p = new Person();
p.name = "Bob";

var object = JSON.parse(JSON.stringify(p));
try {
  object.greet(); // still throws exception
} catch(e){
  console.log("error calling #greet, %o", e);
}

// Step 2: change __proto__
object.__proto__ = Person.prototype;

// Step 3: verify
object.greet(); // now it works!
view raw 3_proto.js This Gist brought to you by GitHub.
// Step 1: same as before

// Step 2: copy properties
var tmp = function(){};
tmp.prototype = Person.prototype;
var t = new tmp;
for (k in object) {
  t[k] = object[k];
}
object = t;
// not that it matters, but object.constructor == Person now. A good thing, so you can reserialize easily.

// Step 3: verify
object.greet(); // now it works!
object instanceof Person // this is also true

Inconvenient, to be sure -- and to make matters worse, there don't appear to be, well, any libraries out there that handles intelligent serialization of Javascript objects. So that's what I'm writing now (but it's not ready yet). Look for it soon though!

12Dec/100

MVC, Games, and a message bus

It seems to me that many approach the use of MVC in games with skepticism, but the more I develop a game in MVC, the more I am reassured in my decision to do so. I operate by the principle that models should absolutely not know about their view(s) (or controllers) -- models should be completely standalone chunks of state and logic that can only reference other models. However, this can present us with a few problems.