Here's what was super quick for me on windows 7. Download the auto installer at nodejs.org and install the .msi on your windows computer.

Go to the start menu and search "cmd". It should find a "cmd.exe". Right-click that and run as admin. Then you should be able to type node --version to verify that it's installed. If the command runs and outputs something like the following, then you're good to go!

c:\>node --version
v0.6.18

Start the tutorial here: http://www.nodebeginner.org/

It's a fairly simple app it has you build, but it will give you enough to start playing around quickly!

Also, this is a great ebook for learning JavaScript interactively: Eloquent JavaScript

My forearms are covered in scrapes from carrying a desk I got off craigslist across hilly blocks of the San Francisco Chinatown. A few days ago, I spent all day lugging heavy things from my friend's place in Oakland to the subway, to the bus stop and to my new room in SF Chinatown. And I did it on a strained ankle. It would have been great to have rented a car or to have hired movers, but I couldn't afford it. Since I can't really justify the cost of a bed, I just got a thin mattress. I don't have a refrigerator and I've been spending a lot of time at a local coffee shop nursing $2 cups of tea for the free wifi.

Not having money sucks.

I'm not completely sure how I arrived at this point. In some ways, I think it's due to my ambition. Six and a half years ago, I was a top paid English teacher in Taiwan, earning over double the average salary for foreign teachers which was already good in comparison to local teachers. Four years ago, I was half owner of an EFL school in Taiwan, and the school was doing okay. Month on month, I was earning less than I had been as an employee before, but still more than most foreign EFL teachers in Taiwan. I put most of my cash savings into the school, but unfortunately got a margin call on my stocks in 2008 in the same month the school happened to be late on payroll. As a result, I was forced to sell most of my long term investments at the worst possible time. Not long after, I started losing my passion for the business. In 2010, I left it to my partners and moved to China as part of a longer term plan to return to the US.

In China, I lived off of savings for over a year. In that time, I recovered a bit from my 4 years of putting in 70 hour work weeks and I also did a lot of learning. I learned to read the simplified characters used in mainland China, improved my drawing and made a few flash games. Eventually, I got hired by a start-up focused on educational games for the iPad and iPhone. I was working with a great group of people and seeing from the inside what a tech start-up looked like. This was exactly what I'd wanted... except that the salary was about half that of what fresh graduates can earn as English teachers in Beijing. Also, rents were nearly as high there as in Taiwan or many parts of the US! As a result, I got used to living in a small room with a kitchen and bathroom I shared with a stranger.

Now that I've made the jump to one of the most expensive parts of the US, my meager savings from China are in dwindling rapidly. So I took the cheapest place I could find -- a 9 square meter room in a Chinatown apartment where I share the kitchen, the bathrooms, and the shower. I may learn some Cantonese here, but it's not a comfortable place to stay. My thin mattress isn't comfortable. Having insanely steep hills in ever direction isn't very comfortable. Somehow, though I find it more motivating than depressing.

I'm firmly past the age when it's socially acceptable (especially for a man) to be floundering financially. I'm entering my mid 30's, with little in savings and no job. But I have the tools. I have some experience with some software, I'm multi-lingual and I have experience starting, building and running a business. I know I can do more, BE more than I ever could have before. The comfort I can take in my discomfort is that it just may give me enough motivation to do it.

Recently, I've been looking at the Windows Phone 7 platform in order to see what it would take to port some iPhone/iPad apps to it. As I first began I was annoyed to discover that WP7 apps can only be built from computers with Windows versions since Vista.

Not wanting to go out and buy a new computer, I decided to try some Emulation and VM options. Parallels is a bit pricey, but it had a free trial that installs the free developer preview of Windows 8. This is actually perfect for me since I want to see the bleeding edge tools in action. The performance is way better than I expected. I've actually got a better Windows Experience Rating on my iMac than on the lone Windows machine at the office! The screenshot tells it all:

Windows 8 running on Lion with Parallels

This thing is a better Windows machine than my office Windows machine!

It can build Windows Phone apps. Next up, Skyrim.

Since my last post here, I've started working at a software start-up. Its product is a platform for educational iOS apps. As a result, I've gained a decent familiarity with objective C and Cocoa. I haven't had a chance to learn much ruby since starting there, but it's been a good experience for me on the whole.

Before I started I was working through a fantastic book by Topher Cyll, called Practical Ruby Projects: Ideas for the Eclectic Programmer. It's got all kinds of cool things from musical composition to genetic algorithms, and each chapter is genuinely interesting in its own right, independent from anything it teaches about Ruby.


Code starts at 2m27s, MacRuby part at 3m, and game at 9m40s

I should offer a warning, though. The publishers lied when it comes to the difficulty of the book! It's way the heck harder than a followup for "anyone who has mastered the basics of ruby". I attempted to tackle it right after an introductory book and it was very challenging. Progress was slow, and it's only the extreme interestingness of the material that has kept me going. I did parts of various chapters and the only one that I fully finished was for a text-based game he called Dinowars.

The next chapter in the book was on how to use RubyCocoa to make a native Mac front end for the game. Initially I skipped the chapter because I didn't have a Mac and I found all the Cocoa stuff alien. But when I returned to it last week, the material was much more understandable! I leapt in immediately! Not only that, but I decided to delve into MacRuby (an even more compelling technology for anyone who wants to use Ruby to build Cocoa), and I've successfully converted Dinowars' front-end to MacRuby.

This video goes over some MacRuby basics, includes a one page program that pops up a window and reads text with a voice synthesizer, and then shows the final result of my Dinowars port.


Resources

Planet cute tiles: Danc's Miraculously Flexible Game Prototyping Tiles
Source Code from the book publisher: Apress
My source code files: tryrc.rb, trymr.rb, trymr2.rb, and mrstrat.rb.

A video game music composer has put up a pretty cool tutorial for people interested in making tunes.  It starts from absolute basics and builds up a simple piece.  If only I had the budget to get that kind of music into my flash games!  Once I get to where I can earn anything significant out of them, .

He did the tutorial with Garage Band. Since, I don't have an iPad,  that piece of software isn't an option for me.  I have been working through some ruby tutorials, though, and so I figured I'd give it a shot in MIDI.  It turns out that it's not that much of a pain to access C libraries from within Ruby. It breaks platform independence, but hey, this is just a fun project, so why not?

It took me a little while to get used to MIDI's notation. A note value of 60 is middle C. 59 is half a step lower, 61 is a half step up, and so on. That means that to go up an octave, it's necessary to increase the note value by 12 instead of 8. After adjusting to this, it wasn't too tough to get the chords Whitaker used in his blog post. Well, hopefully they're right! I also started listening to the sound files further down the post, but didn't get that far in deciphering the melody. Here's the ruby code to generate what I've gotten so far:

 


require 'dl/import'

class LiveMIDI
   ON = 0x90
   OFF = 0x80
   PC = 0xC0
   
   def initialize
      open
   end
   
   def note_on(channel, note, velocity = 64)
      message(ON | channel, note, velocity)
   end
   
   def note_off(channel, note, velocity = 64)
      message(OFF | channel, note, velocity)
   end
   
   def program_change(channel, preset)
      message(PC | channel, preset)
   end
end

if (RUBY_PLATFORM.include?('mswin') || RUBY_PLATFORM.include?('w32'))
   class LiveMIDI
      #Windows code
      module C
         extend DL::Importable
         dlload 'winmm'
         
         extern "int midiOutOpen(HMIDIOUT*, int, int, int, int)"
         extern "int midiOutClose(int)"
         extern "int midiOutShortMsg(int, int)"
      end
      
      def open
         @device = DL.malloc(DL.sizeof('I'))
         C.midiOutOpen(@device, -1, 0, 0, 0)
      end
      
      def close
         C.midiOutClose(@device.ptr.to_i)
      end
      
      def message(one, two = 0, three=0)
         message = one + (two << 8) + (three << 16)
         C.midiOutShortMsg(@device.ptr.to_i, message)
      end
      
   end
elsif RUBY_PLATFORM.include?('darwin')
   class LiveMIDI
      #Mac code here someday
   end
elsif RUBY_PLATFORM.include?('linux')
   class LiveMIDI
      #Linux code here someday
   end
else
   raise "Couldn't find a LiveMIDI implementation for your platform"
end

def play_note(channel, note, velocity, sleep_time, midi)
   midi.note_on(channel, note, velocity)
   sleep(sleep_time)
   midi.note_off(channel, note)
end

def play_chord(channel, notes, velocity, sleep_time, midi)
   notes.each do |note|
      midi.note_on(channel, note, velocity)
   end
   sleep(sleep_time)
   notes.each { |note| midi.note_off(channel, note)}
end

midi = LiveMIDI.new
#Middle C chords, Middle C is 60 and each number up or down is a half-step
I = [60,64,67]
ii = [62,65,69]
iii = [64, 67,71]
IV = [65, 69, 72]
V = [67, 71, 74]
vi = [69, 73, 76]

midi.program_change(1,32) #to use for the melody if I can figure it out
play_note(1,64,100,1,midi)
play_note(1,64,100,0.25,midi)
play_note(1,64,100,0.25,midi)
play_note(1,64,100,0.25,midi)


midi.program_change(0, 3) # set channel 0 to piano

sleep(1)

midi.note_on(1,64,100)
4.times do ||
   play_chord(0, [55,64],100,0.25,midi)
   play_note(0,48,100,0.25,midi)
end
midi.note_off(1,64,100)

4.times do ||
   play_chord(0, [57,65],100,0.25,midi)
   play_note(0,50,100,0.25,midi)
end

4.times do ||
   play_chord(0, [60,69],100,0.25,midi)
   play_note(0,53,100,0.25,midi)
end

4.times do ||
   play_chord(0, [64,67],100,0.25,midi)
   play_note(0,48,100,0.25,midi)
end

4.times do ||
   play_chord(0, [64,69,72],100,0.25,midi)
   play_note(0,57,100,0.25,midi)
end

4.times do ||
   play_chord(0, [62,71],100,0.25,midi)
   play_note(0,55,100,0.25,midi)
end

4.times do ||
   play_chord(0, [64,67,72],100,0.25,midi)
   play_note(0,48,100,0.25,midi)
end
play_chord(0,[48,52,55,60],100,1,midi)

Download it and run it on Windows to hear it play!

Tune from Whitaker Blackall

I think the best introductory book to programming that I've ever seen is Learn to Program, by Chris Pine.  My buddy I was staying with last summer went through it while I was there and made absolutely fantastic progress.  Despite never having programmed before, really, he tore through it in a week or two and got enough out of it to start programming simple scripts to help with his research job.

The entire book is taught in Ruby, but I don't think the language used matters that much.  The thing is it teaches concepts basic to almost any kind of programming -- functions, classes, recursion, blocks, etc...   And more importantly, it makes them fun!  Even the very simple exercises, such as "deaf Grandma" and "angry boss" were amusing.  My friend has ended up working almost entirely with Python, but everything in the book was still useful and there was little pain in switching to a new language compared to the difficulty of getting started.

When I first got curious about Ruby myself three years ago, I tried the Pick-axe book and gave up out of boredom.  It really could have used regular programming challenges or problems at throughout the book.  Unfortunately almost all the other resources that were around at the time were focused on Rails.  I really wish I'd found this book back then.

Some free online lessons that later became part of the book can be found here: http://pine.fm/LearnToProgram/

Last week I went to Taiwan to visit a bunch of old friends. I stayed at my buddy Jay's place and had the chance to see him try out my most recent game. In about 15 minutes, I got more useful feedback from that than I had from dozens of messages and emails from various people online.

When he first started, he skipped the instructions. That's pretty much what I'd expected. But he wasn't sure how to get gold in the game. The shop interface confused him due to the way I'd named things. Selecting Return took him to the main menu of the shop, instead of out of the shop as he'd hoped. The way selling worked was a surprise. In the end, he only had money to buy a couple of terrible pieces, with which he promptly lost. If not for the fact that he knew the maker of the game, he never would have tried it again.

Seeing someone repeatedly curse (or at least want to curse) the interface for something you've made is pretty enlightening. I knew exactly which spots were annoying. It didn't take long at all to rename Return into Leave. I also eliminated the hierarchical structure of the shop altogether and made a menu for all the options stay at the top at all times. This way users could browse the blocks for sale and then go directly to looking at the ones they already had without having to go back to a main menu first. Jay gave several other interface suggestions, some of which I've already implemented.

The other major problem I realized was that my game was way the heck too hard. This I also blame on doing almost all the playtesting myself. As I built the game, I became very familiar with its interface and with the strategies needed to do well. What felt easy to me was way to hard for anyone playing it for the first time. As I saw my friend play the game, I slowly came to the realization that there were things I'd included in the game, things that I'd worked hard on that nobody except myself ever saw. What's the point of creating a super powerful item that slows time in the game if nobody ever knows of its existance? I've heard that this is a common problem with playtesters who continue testing a game for too long-- they get a totally skewed idea about its level of difficulty.

As a result of seeing the game played, I now understand why the kongregate rating was so poor. I also have a clear path towards improving the experience. With that knowledge, I've decided not to work on my robots with lasers game idea yet. I'm going to improve Block Merchant. As far as I see it, the game wasn't done when I released it. Unfortunately, it's not really going to get much more feedback from kongregate users, but I can at least make it a better game. I think I'll budget myself 15 hours of work on it before I try putting it up on newgrounds or another site.

I put significantly more effort into Block Merchant than I did into the last game. The programming logic was more difficult; I didn't get it working properly until after thinking of a way of making a grid system. There was actual artwork, however simple involved. I also made made a shiny title screen composed of multiple alpha layers. I definitely learned a decent amount making it, but it wasn't well liked at all by the few people who played it on Kongregate. I got some feedback from them at least, but it is still a bit of a bummer. I think it's possible that the bar for free flash games is higher than it was six months ago. There are so many others such as myself who have followed various tutorials and started making games that the casual gamer's patience for familiar concepts is much less than it used to be.

I see two ways to go from here.

  1. Make improvements. It still won't make much of any revenue since it's not that novel. It will be much better liked after getting some polish, though. Also, it might be good for me to try to actually make something a bit higher quality.
  2. Make a new game. I'm thinking of programmable robots that you fight against each other. It would probably have more of a chance of gaining some traction. I'd also learn more from a new project than continued work on an old one.

My third full flash game is finally done! While my last one, Juggle Basher was essentially just a breakout clone, Block Merchant goes beyond the many tetris clones out there. It has different pieces, a new game mechanic of money and a shop which allows you to buy and sell blocks to optimize your set. The programming side of things was definitely a bit harder than the breakout clone, but where I really spent more time was the graphics. I probably put as much time into making the intro screen and the shop screen as into the programming. Fortunately, a fellow konger who goes by zoranac offered to help out with the music. He's been churning out all kinds of music in the Kongregate colabs.

As usual, I've put the game up on Kongregate and set it up to hook into their high scores api so your achievements will get recorded.
(more…)

This is possibly the weirdest bug I've ever seen. My flash program was working fine from within the debugger and from Adobe's swf player built into Flash CS5. However, when I put the swf into a web page, I got errors from things not being deleted.

How I make sure everything is deleted

Basically, I've borrowed what I'm sure is a common method of keeping track of objects from the Kongregate tutorials. Whenever I create a sprite or a text object or whatever, I push the object to a list that's a class variable. Then when the objects need to be destroyed, it's easy to go through the list and find them all. One example of this was in my side-scrolling space ship shooter game. Every time the ship fired a bullet, the bullet sprite would get added to the screen and the bullet would be added to a list. When the main ship got destroyed, then a function would be called to go through the list of bullets and remove them from the screen, turn off their event listeners, etc...

The code that caused the weird bug (only on some platforms):

function destroy() {
	for (var i in components){
		components[i].destroy();
		delete components[i];
	}
	removeEventListener("enterFrame", enterFrame);
	if (this.parent && this.parent == stage) stage.removeChild(this);
}

The code that works everywhere:

	
function destroy() {
	for (var i = 0; i < components.length; i++){
		components[i].destroy();
		delete components[i];
	}
	removeEventListener("enterFrame", enterFrame);
	if (this.parent && this.parent == stage) stage.removeChild(this);
}

Huh? How the heck is one different from the other?