Categories
Huffington Post

Bloomberg West TV Interview

Today I was interviewed by Nicole Lapin on Bloomberg West. All-in-all a very pleasant experience. The last question was a bit of curve ball: The topic was “Interactive Election: The Psychology of the Comment” and thus I didn’t expect a Spotify vs. Apple question. Luckily, I am always prepared!

Categories
Blogging

My Huffington Post Blog Posts

I’ve been writing a weekly blog post for the Tech section of the Huffington Post. Here are links to what I have written so far:

I’ve learned a lot from writing these blog posts and I’ll continue to do until our editors lock me out of the CMS. Reading the commentors as they alternately boo and cheer, correct my grammar and spelling, and point out technical mistakes is awesome!

Figuring out what to write about is always a panic. I don’t have time prepare and want to tie each post to something topical. The other hard thing is keeping each post short. Nobody, not even me wants to read more than 1500 words of John Pavley 🙂

Categories
Nerd Fun Product Design Programming

HyperCard: What Made it Leet

I posted a blog entry on HyperCard yesterday on The Huffington Post: HyperCard: The Original Bridge Over the Digital Divide. From the comments and tweets that I got it was pretty clear that us older hackers have fond memories of HyperCard. But there’s the rub–Us older hacker. Kids today, i.e., people in their twenties, missed out on the whole HyperCard phenomenon.

The children of HyperCard are ubiquitous! Every web browser, every presentation app, and even Apple’s iBook Author tool and Adobe’s AIR environment are Jar Jar Binks to HyperCard’s Qui-Gon Jinn.

But like Jar Jar himself, HyperCard’s children are flawed. All these apps and tools that link, animate, and script are over-specialized or over-complicated.  iBook Author is a great example. It’s a quick and easy (and free) way to create an app that runs on iPhone and iPad but only if you want that app to look and feel like a high school text book. Not sexy!

On the other end of the spectrum is RunRev’s LiveCode. It’s the most HyperCard-like of HyperCard’s successors, allows you to import HyperCard stacks (originally), uses many of the same stack and card metaphors, and provides a programming language very similar to HyperTalk. Unfortunately LiveCode has become a tool for creating serious desktop and mobile apps. It’s become as complex as Adobe Flash/Flex/AIR and almost as expensive. I have to give points to RunRev for keeping the dream alive and they deserve to generate a profit but it’s not about 10-year-old kids and school teachers making interactive lessons anymore.

Here’s my list of what made HyperCard great. I hope someone picks it up and runs with it.

  • You could do a lot but you couldn’t do everything with HyperCard. Limitations are a great way conserve complexity and keep doors open to the general public.
  • HyperCard was a general “software construction kit”. You could create a presentation but it wasn’t optimized for presentations or anything else. In its heyday HyperCard was used for everything from address books to to calculators to role playing games but it always felt a little amateur and frivolous.
  • HyperCard was free, preinstalled, and came with a great set of sample stacks. Some people just used the stacks as they came out of the box. Others noodled around with a bit of customization here and there. A few brave souls created new stacks from scratch. But it didn’t cost a dime (originally) and was easy to find.
  • HyperCard’s authoring tools were bundled with it’s runtime environment. Any stack (originally) could be opened and every script inspected. If a stack did something cool you could easily cut-and-paste that neat trick into your own stack.
  • HyperCard’s scripting language, HyperTalk, was very very English-like. More English like than AppleScript and 10,000 times easier for the amateurs and kids to master than JavaScript, Python, Ruby, or Processing. I’m sorry but “for (var i = 0; i < x; i++)” is just not as readible as “repeat with x equal to the number of words in line 1” to normal literate humans. (Python comes close, I give it props for trying.)
  • HyperCard stacks looked like HyperCard stacks. You could easily spot a stack in a crowd of icons and when it was running HyperCard stacks had their own visual language (originally). This visual identify made HyperCard authors feel like members of a special club and didn’t require them to be User Experience experts.

Limited, Free, Simple, Open, Accessible, Generalized, Frivolous, Amateur; The characteristics of greatness that also define what is great about the World Wide Web (originally).

Note: The careful reader might wonder why I’m clarifying my statements with the phase “(originally)”. Towards the end of its life HyperCard added complexity and locking and became something you had to buy. The parallels with the closed gardens and paywalls of today’s Inter-webs  are a bit uncanny.

Categories
Nerd Fun

The Little Computer that Taught Me

The TI 99/4a from Texas Instruments still looks pretty awesome after 32 years!

The personal computer I really wanted to work with back then was the Apple II but as a university student of modest means the big Apple was too much for my bank account to handle. I considered the Commodore VIC-20 and Atari 800, both more popular but they were inferior engines of calculation. The TI 99/4a contained a true 16-bit CPU that might be considered one of the first RISC chips available to home users. But I didn’t know anything about CISC vs RISC or 8 vs 16 bits. I only knew that I could afford it, that it ran BASIC relatively fast, and I could save my programs to cassette tape. I no longer have a TI 99/4a but I still have the matching cassette recorder, which also doubled as an ordinary audio cassette player.

Back then there was a truly great hobbyist computer magazine called COMPUTE! Every month it would contain the source for several BASIC and machine code programs for each of the home computers of the day. I would dutifully type in each program for the TI 99/4a and then modify it beyond recognition. After a few months I started creating my own, original works, that served no other purpose but to amuse me. My TI99/4a started to attract other nerds (I don’t think we had the word hacker back them) and thus began a journey that took me from painting and drawing pictures with brushes and pens to developing real software on serious computer systems.

The simplicity and limitations of the TI 99/4a gave me an advantage that today’s young hackers lack: Focus. There was no question about where to begin and what to begin with. Most importantly I had to type in every line of code myself: No cut and paste (it had not been invented yet) and no code editors with auto complete. All my code was DRY because wet code was too time consuming to type in.

Categories
Argument Nerd Fun

How Engineers Will Win

Before reading this, you should read Why Engineers Never Win and Why Engineers Should Win.

Ok, now we’re all caught up.

I’m optimistic. Yes, I know the world is hurting. I see how the people trying to do good often make things worse. I can’t claim to be insightful when I observe how we celebrate buffoonery and berate competency. (At least the Romans got bread with their circuses.)

I’m optimistic because engineers have become poets and code has become poetry.

Every age, every culture, every society is measured by the breath and depth of it’s poetry and the brilliance of it’s poets. This poetry can be visual or musical or sculptural or theatrical or even wordy. Sometimes it’s hard to identify the poetry, hidden behind fashion and fads but it’s there if you look long and hard and unblinking.

A month ago I had an opportunity to visit the Louvre for the first time, in person. I only had a couple of hours so I made beeline for the Ancient Greek sculptures. My mature interest in making art, oops, I mean visual poetry, was born from my experience of the Kourus and Kore gradually coming to life from stiff abstractions in the 7th century BCE to expressive examples of humanity in the 5th century BCE. Walking past these sculptures in the Louvre was like watching a culture awaken from myth to science.

And that same transformation is taking place today: The boxy utilitarian desktop computers of the last decade have become light and glassy iPhones and iPads; The awkward and inflexible HTML websites of yesterday have become elegant and animated HTML5 web apps; CDs and DVDs with hard data limits have become unlimited streams.

We are waking up. Engineers are not arguing for a better world, they are not waiting for the next election or for military action or for protesters to start marching; Engineers are writing new poems that express our better natures in code and chips.

Admittedly, things are a little messy right now. Tech isn’t always used for good. But a program or a device that gives an individual the research and communication power of a corporation or government is inherently good.

Already we have tech poetry that is starting to enable individuals to navigate and bypass complex legal and political boundaries. This is true equality: When you can talk to anyone, anywhere, without permission from anyone else. People are talking to people without adult supervision on Reddit, Facebook, Tumblr, Twitter, Ventrillo, and more. And it’s not the end of the world–rather it’s the start of the world, a new kind of unfettered speech.

Poets know that language both enables communication and limits expression. That why they use novel formulations and metaphors: A great poet breaks free of the constraints imposed by his native tongue.

We can’t solve the problems hurting the world with the tools and languages that created these problems in the first place. But engineers will solve them with ideas that can only be etched in silicon and written in RAM.

Categories
Cocos2d-iPhone Programming

ARC Memory Management in iOS 5 and Cocos2d-iPhone 2.0

My rewrite of Dungeonators is crawling along at a glacial pace. Mostly because I can only work a couple of hours a week on the project. But the iOS 5 way to manage memory with ARC (automated reference counting) is making the process far less painful than it was the first time I wrote my game. ARC uses annotations and some new key words to manage memory on your behalf. It works very well if you’re doing simple client-side game development and don’t have to worry about backward compatibility with iOS 4.

Here is an example of how ARC changes your life for the better…

In the old days you would declare out your ivars, declare your properties, then synthesize and map them together, and release them in a dealloc method. This little design pattern required 4 repetitive lines of code for every ivar (instance variable) and engendered flamewars about  coding style and where underscore should go (if you thought it was necessary to distinguish an ivar name from a property name).

Pre-ARC Entity.h

#import "cocos2d.h"
@interface Entity : CCSprite {
BOOL isActive_;
NSString * name_;
}
@property (nonatomic) BOOL isActive;
@property (nonatomic, copy) NSString * name;
@end

Pre-ARC Entity.m

#import "Entity.h"
@implementation Entity
@synthesize isActive = isActive_;
@synthesize name = name_;
- (id) init {
  self = [super init];
  if (self) {
    isActive_ = YES;
    name_ = @"Fang";
  }
  return self;
}
- (void) dealloc {
  [name_ release];
  name_ = nil;
  [super dealloc];
}

In this new modern era of automated reference counting I just declare properties, I don’t worry about accessing the ivars directly, and I don’t write my own dealloc. It’s a lot less code in a complex game where characters and objects have dozens of properties.

Post-ARC Entity.h

#import "cocos2d.h"
@interface Entity : CCSprite
@property (nonatomic) BOOL isActive;
@property (nonatomic, strong) NSString * name;
@end

Post-ARC Entity.m

#import "Entity.h"
@implementation Entity
@synthesize isActive;
@synthesize name;
- (id) init {
  self = [super init];
  if (self) {
    isActive = YES;
    name = @"Fang";
  }
  return self;
}

To get Cocos2d-iPhone to work with ARC was really easy: I just replace the NSAutoreleasePool object in main.m with the new ARC friendly @autoreleasepool annotation. (I might not have had to do this but it’s supposedly more efficient.)

int main(int argc, char *argv[]) {
//    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
//    [pool release];
//    return retVal;
  int retVal;
  @autoreleasepool {
    retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
  }
  return retVal;
}

The downside, as I stated above, is that your app will only run on iPhones, iPads, and iPods running iOS 5 and you need to use Cocos2d-iPhone 2.0. But I think that’s a fair tradeoff. Backward compatibility is a killer of the artistic soul and should be avoided where possible. To Err is human, but to upgrade is divine 🙂

Check out Ray Wenderlich’s excellent ARC tutorial for all the gritty details!

Categories
Music

Personal Music Discoveries for 2011 (Thanks Spotify!)

One of the best parts about working at Spotify is being paid to listen to music. After all some has to do the quality assurance! Actually, our QA guys and gals do a great job… but I can’t help myself 🙂

This year I’ve spent a lot of time with my old favorites, recapitulating my youth and young adulthood into playlists. You can find all my playlists here: JPavley’s Spotify profile.

But the known is not the topic of this blog post: Today, one of the final days of 2011, I want to tell you about unknown music.

Spotify has over 15 million tracks available in the US and I doubt that I’ve listened to more than 3000 different songs in my entire lifetime. It’s hard to guess but generally as we age our tastes settle and we stick to what we know. As much as I love the familiar I love the thrill of discovery even more! It’s painful for me to think about music that I may never hear yet that I would love if I had the chance to heard it.

Here are my top 10 personal music discoveries for 2011*:

10. Wire – Red Barked Trees Tension and power slowly build up “to find the healing red barked trees”.

9. Harald Grosskopf – VIVACISSIMO CON MOTO – Album Mix Like a mini sci-fi epic Grosskopf’s a great sound track for living in the future.

8. Röyksopp – Keyboard Milk Scary but mentally danceable.

7. Zomby – Witch Hunt Another scary, haunting song with a fast tempo and bonus gun shots.

6. The Cinematic Orchestra – Evolution – versao portuense Slow and relentless and dreamy.

5. Digitalism – Miami Showdown I grok the repeating patterns that ebb and flow around a central beat.

4. 8 Bit Weapon – 64 Gigabit Mario Epic Like something out of a electronic Miyazaki movie.

3. Wye Oak – Two Small Deaths Could be electronic-pattern-based but actually made by Indy humans.

2. Lullatone – My Second Favorite Song In The World I could live inside this song for ever.

1. John Fahey – Sligo Mud Starts out like a blue standard and moves into abstract and concrete bliss.

Each of these artists is new to me. Hearing each track for the first time was more like remembering something that was missing than finding something new.

Here’s the complete playlist: Personal Discoveries 2011

* This is new-to-me not necessarily new-to-the-world. There is a lot of back catalog that I’ve missed over the years!

Categories
Cocos2d-iPhone Product Design

Dungeonators Battle UI Redesign


There is nothing quite like real user feedback. The Dungeonators game that I started coding about a year ago has been through several design iterations. Before I wrote a line of code I mocked up the whole UI and tested that on my friends and kids (paper prototype, an honorable UI design tradition). And with each development build I tested everything again and even enlisted strangers. I must have played though the final release candidate a 100 times. (It was then that I realized that game programmers must get sick of their games if they properly test them!)

When I uploaded Dungeonators to the App Store on 14 October 2011 I was pretty confident about the game play and the user interface. Famous last words as they say 🙂

After an initial healthily growth curve Dungeonators installs tanked:


The message I get from this user adoption curve was simple: Dunegonators stinks!

So I went back to the drawing board to search for the stinky bits. After much reflection I realized three things:

  1. Dungeonators is too hard for casual users and too easy/dumb for hardcore gamers. People who play MMORPGs like World of Warcraft punch through my game. People who play Angry Birds get stuck around level 1.6. (Which is as far as you can go if you don’t know what you’re doing.)
  2. People don’t know what to touch. They want to touch the avatars and not the raid and spell frames. If you don’t know what raid frames and spell frames are then you are not going to get my game.
  3. I was going to have to fix this. I could fix this problem with a lengthy tutorial or FAQs. But Dungeonators is causal game not productivity software. I never read manuals and skip tutorials. I expect my audience to have the same level of self respect!
So here is the new battle UI that tries to clean this mess up:
  • The good guy raid frames (on the left) are no longer touchable: They just display status. I couldn’t find a casual user who knew what a raid frame was so I got rid of raid frames.
  • Good guy spell frames are no longer associated with good guy raid frames: Spell frames are now modeless and never hidden. Each good guy has two spells available 24/7. As the game progress the spell are automatically upgraded. I’ll have to rewrite the game mechanics to handle the fact that the total number of available spells has gone from 4 x 6 (which I understand is 24) to a mere 8. But that actually makes Dungeonators a heck of lot simpler to program and to play.
  • The bad guy raid frames are still touchable and still enable the player to switch targets. But in the original UI you could have separate bad guy targets for every good guy. In the revised UI all the Dungeonators are synchronized. It’s a gross simplification that is all for the best.
  • Touching the center of the screen, where the avatars live, is still not part of the game play but if you do, the game will pause and bring up the main menu. I was able to kill two birds with one stone: No main menu button and a valid response to a user touch. Feedback is everything thing: In the original design touching the center of the screen was ignored and could have been interpreted as the game freezing up.
In general I learned what I thought I always knew: iPhone games have to be simple and causal gamers don’t have the time or energy for complex mechanics. But in practice I learned a lesson that every battled hardened game developer must know after their first game is released: There is no better test case than the real world!
Categories
Cocos2d-iPhone Programming

Sprite Playground

I wrote a little Cocos2d-iPhone test app and committed the project to GitHub. (Like every dutiful hacker should.) You’re welcome to download the project and fool around with the code.

My goal was to figure out how to create a composite sprite, make sure it could respond to touches, and rotate and move it round the screen. With a little trial and error I got it working. Here’s how I did the hard parts:

I created a sprite from an PNG file and got it’s dimensions:

CCSprite * cocos2dGuy = [CCSprite spriteWithFile:@"avatar_n1_tang.png"];
CGSize spriteSize = cocos2dGuy.textureRect.size;

Then I created a CCNode to be the parent of my sprite sandwich. (I originally tried to use my cocos2dGuy CCSprite as the parent but Cocos2d stacks added on top of partent nodes and I wanted the particle effect under the cocos2dGuy not on top of him.) I set the size of the CCNode to the dimensions of the cocos2dGuy so that when you touch the CCNode it responds as if you’re touching the image. Then I add the CCNode to the layer. It’s also important to set the CCNode’s anchorPoint to the center (0.5, 0.5) as it’s default is bottom-left. CCSprite default to center anchorPoints and I want my CCNode to act like a proper sprite.

CCNode * composite = [CCNode node];
composite.anchorPoint = ccp(0.5,0.5);
composite.contentSize = spriteSize;
composite.position = centerPt;
[self addChild:composite z:0 tag:kCompositeTag];

Next I added the cocos2dGuy sprite to the center of the composite CCNode. These two entities are now both the same size and stacked on top of each other. (It’s probably not necessary for me to set the cocos2dGuy’s anchorPoint and so I’ll remove that line of code down the road.)

cocos2dGuy.anchorPoint = ccp(0.5, 0.5);
CGSize compositeSize = composite.contentSize;
CGPoint compositeCenterPt = ccp(compositeSize.width/2,compositeSize.height/2);
cocos2dGuy.position = compositeCenterPt;
[composite addChild:cocos2dGuy z:1 tag:1];

Finally I created the custom CCParticleSystem from a Particle Designer file and added it to the composite CCNode but at a lower Z value show it shows up under the cocos2dGuy sprite. See how I had to set the position and the anchorPoint to ensure everything lined up.

CCParticleSystem * fx = [ARCH_OPTIMAL_PARTICLE_SYSTEM particleWithFile:@"fireball_small_fast_green.plist"];
fx.anchorPoint = ccp(0.5, 0.5);
fx.position = compositeCenterPt;
fx.duration = kCCParticleDurationInfinity;
fx.scale = 2.0f;
fx.autoRemoveOnFinish = YES;
[composite addChild:fx z:0 tag:1];

Movement and animation are easy in the world of Cocos2d. I really like the visual effect of CCEaseExponentialInOut. It has a nice punch.

Handling touches are bit harder. I had to remember to set self.isTouchEnabled = YES in my init method and override both registerWithTouchDispatcher and ccTouchBegan. The key bit of code for responding to a touch is isTouchForMe:

bool hit = false;
for(CCNode * node in [self children]) {
    if(node.tag == kCompositeTag) {
         hit = CGRectContainsPoint([node boundingBox], touchLocation);
         if (hit) {
             [self hiliteSprite:(CCSprite *)node];
         } else {
             [self turnSprite:(CCSprite *)node andAttackPoint:touchLocation];
         }
    }
}

The main thing here is to give each touchable node a unique tag and test each node in the layer for that tag. If you touch the sprite he inflates for a moment. If you touch an empty part of the screen the sprite turns and launches himself at your finger. Ouch!

Categories
Cocos2d-iPhone Programming

Cocos2d-iPhone Sprite Rotation to an Arbitrary Point

I had some time during the Thanksgiving weekend to work on Dungeonators. I’m hoping to get an upgrade out to the App Store soon. One thing I needed //TODO: is refactor my rather poor implementation of rotating a sprite to face another sprite. My original code worked ok, in a roundabout way, but was ugly and mysterious.

(My iPhone game is full of ugly mysterious code: As I implement my ideas in code I first focus on getting it to work. Then, if I have time I go back and fix it to work cleanly. Generally cleanly means boiling the code down to the fewest number of lines possible, making it as functional as possible, and using functions from the operating system or open source code libraries as much as possible.)

I won’t show you my original sprite rotation implementation. Some things are too gross even for the Internet. Let’s just say it was written as if I was trying to remember high school trigonometry by trial and error.

Instead below is the final implementation, useful to any Cocos2d-iPhone programmer who wants a sprite to rotate to face an opponent at any point on the screen:

- (void) rotateSourceSprite:(CCSprite *)sourceSprite toFaceTargetSprite:(CCSprite *)targetSprite {

    // Calculation
    CGPoint difference = ccpSub(sourceSprite.position, targetSprite.position);
    CGFloat rotationRadians = ccpToAngle(difference);
    CGFloat rotationDegrees = -CC_RADIANS_TO_DEGREES(rotationRadians);
    rotationDegrees += 90.0f;
    CGFloat rotateByDegrees = rotationDegrees - sourceSprite.rotation;

    // animation
    CCRotateBy * turnBy = [CCRotateBy actionWithDuration:0.5f angle:rotateByDegrees];
    CCEaseIn * ease = [CCEaseIn actionWithAction:turnBy rate:4];
    [sourceSprite runAction:ease];
}

And here’s how it works, just incase you’re curious…

  • The method takes a source sprite and as target sprite as parameters. After it runs it will rotate the source to face the target.
  • The calculation part uses Cocos2d helper functions and macros (ccpSub, ccpToAngle, and CC_RADIANS_DEGREES) to figure the maths. In my original implementation I had written my own versions. Using the Cocos2d API makes my code easier to read and perhaps faster.
  • The maths work like this: Create a vector out of the distance between to points. Convert the vector to an angle. Convert the angle from radians to degrees and negate it*. Add 90 degrees to the angle to get the proper orientation. (The +=90.0f value is game specific: My sprites are rotated 90 degrees to start with.) Subtract the penultimate result of the calculation from the current rotation property (angle) of the source sprite to get the final result (the amount to rotate by).
  • The animation, which could easily be factored out into a method of its own, uses Cocos2d’s CCRotateBy and CCEaseIn to turn the source sprite to face the target in half a second. This part didn’t change from the original code. I didn’t factor it out because in my game I always use these two pieces together. I don’t like to do too much work in the abstract because I usually end up making my code too complex.

* The need to negate the value produced by CC_RADIANS_DEGREES is a bit of a mystery to me. If I don’t do it my sprite ends up facing in the opposite direction.