So as promised, here's more data about how the release of Piratizer Lite helped the sales of the full version of Piratizer. As expected, it did create a light (ha) boost in sales. Here's the graph - the large spike around June 1 was about when the Lite version was released:
So it's still a little early to conclusively call it a trend, but the release of the Lite version seems to have boosted sales of Piratizer by about 4-5x. Sales are now around 20-25 per day.
The one thing I know the sales won't do is stay constant, but imagining that they did, 25 sales per day would be about 9000 per year. Add in say 5 more apps pulling similar numbers and you could have yourself a nice little source of passive income, which is a good thing to have during these days of recessions and layoffs.
It's looking more and more like Piratizer won't achieve the great success of CubeCheater, which is what I had feared and intended to test by making the app. Certainly with 50,000 apps now in the App Store, only a select few are going to be making any real amounts of money, given the way the system is set up.
It's been a few weeks since Piratizer was released, so it's about time for an update. Unfortunately the update is not all that good - yet.
After an initial burst of purchases by friends and family (thanks everyone!), daily sales have slowed and and leveled off in the single digits:
Piratizer Sales - First Three Weeks
The problem is the same one that most other iPhone apps face: nobody knows that the app exists. With 40,000 other apps on the App Store, it's impossible to find any apps that aren't in the Top 100 lists, unless you hear about the app through some other means, and then search for it. The trick is to somehow get enough people to buy the app in one 24-hour period that it shows up on the top lists, where lots of other people will see it and then buy it (hopefully).
So far the response from existing customers has been positive, so I'm hoping that the app will be popular if it can just get onto the charts.
CubeCheater was able to really take off once it got mentioned by Wired, Gizmodo, and other high-profile sites. Unfortunately I'm not sure that Piratizer has quite the same "cool factor" required to get mentioned on one of those sites (of course I have submitted it for review to all of those sites, but no luck so far - they probably get hundreds of apps submitted every day, so it's difficult to stand out of the crowd).
Not all hope is lost, though: there are still a lot of other opportunities to increase sales. Since "app visibility" is such a large problem, enterprising developers have come up with lots of ways to tackle it. The first big one I'm going to try is the "Lite" strategy: make a Lite version of the application which has limited features and advertises the full paid version. Huge numbers of people download all the free apps they can get, so any free app is almost guaranteed to be downloaded many times, at least if it's any good. The popularity of the free app will drive some fraction of users to "convert" up to the paid app.
This "demo" strategy has existed forever, but its power on the App Store was only really quantified with the success of the iShoot app, as chronicled in this Wired article. Ethan Nicholas's iShoot tank game was selling slowly until he released iShoot Lite. The Lite version was downloaded 2.4 million times, and that caused the paid version to be downloaded 320,000 times (all numbers are from February - they are certainly higher now). He was smart, though: his app cost $3, so he pulled in a cool million dollars from those sales.
So if Piratizer Lite has even a fraction of that kind of success, then I'll be happy. It's waiting in the Apple approval queue now and will hopefully be approved soon. Once it's been out for a while, I'll make another post about the results!
Late last night Apple approved Piratizer for sale on the iPhone App Store! I only noticed it this morning when I unexpectedly received a sales report saying it had sold 9 copies on Sunday (I still haven't received the email notification from Apple).
Anyway, it will be quite interesting to see the total sales for the first full day it's available for sale (today). Before beginning the full marketing blitz, we need to build up a good stable of reviews and fix any critical bugs that the early users find (hopefully there won't be any). If you'd like a free promo code to download and review the app, let me know!
We finished and uploaded the website just in time. There are still a few things to tweak, but it's pretty much complete. Check it out over at piratizer.com!
I'm still trying to figure out how to fix the thumbnail of the YouTube video to display properly, but at least the video itself works OK. Speaking of the YouTube video, here it is:
If you're reading through an RSS reader or otherwise can't see the embed, here's a link to it on youtube.com: http://www.youtube.com/watch?v=yMlJmdyy-zM.
My trip to China and the craziness immediately beforehand and afterward delayed my new Piratizer iPhone app a little bit, but I'm pleased to note that it's back on track and should be sent off to Apple early next week! There are still a few cool features left to code up, but it's mostly all done.
Here are some sneak preview pictures:
Piratizer uses face-recognition technology to find the faces of all of the people in your photographs and automatically turn them into pirates. There are all kinds of pirates - Buccaneers, Corsairs, Wokou, Vikings, and maybe a super-secret fifth pirate type if we have time.
There's a large collection of all kinds of professionally illustrated pirate gear - hats, eye patches, jewelry, beards, hooks, peg legs, parrots, monkeys, swords, scars - you name it!
Once you're done editing your photo, you can save it and then email it, assign it to a contact, upload it to Facebook, etc. Here's me as a Buccaneer.
First, the obligatory chart of App Store sales:
As you’d expect, sales saw a big boost after getting publicity, and then dropped back off afterwards.
Many sites include “via” links as a way to give credit to the people they got some content from. It’s interesting to plot these links in and see how content spreads through the blogosphere. Here’s a link graph, with solid lines indicating confirmed “via” links, and dashed lines representing my best guesses as to how the content spread:
The next interesting bit of data is to look at YouTube’s new “Video Insight” feature, which tracks a lot of data about how your videos are viewed. The view count graph is about what you’d expect: a huge spike and then near-total falloff:
The YouTube viewer demographics are more interesting:
I was surprised at the age range: well more than half of the YouTube viewers were over 35 (I would have expected the majority to be under 30). The gender breakdown is 90% male, 10% female - I am actually a little surprised it was skewed this much. Both of these statistics probably have more to say about Wired & Gizmodo readers than they do about YouTube viewers or iPhone owners (since the vast majority of YouTube views came from embeds on those two sites).
The last bit of interesting data I have is from the hits directly on my CubeCheater web site. Here’s the graph of daily pageviews, which shows a spike similar to the others, though its shape is slightly different:
The HTTP referrers also reveal some interesting tidbits:
Surprisingly, Yahoo is by far the #1 referrer, most likely due to the fact that the Yahoo Games article did not include an embedded YouTube video: it was the only one which prominently linked to the CubeCheater website directly.
The vast majority of search keywords during this period were either cubecheater or cube cheater. For these terms at least, Google Search apparently has about 20 times the traffic of either Yahoo Search or Live Search.
CubeCheater has been on sale for one week now, so I figured I would post the sales stats since they are pretty different from what I was expecting them to be like. It’s always a question about whether or not you should post your sales stats, but I think that one week of data doesn’t reveal too much. It was really useful for me when other iPhone app developers posted their stats, so maybe this info will help others who are thinking about jumping in too.
While I was making the app I was expecting to get only one or two sales until the app was reviewed by a prominent iPhone site or blog, at which point there would be a spike of sales, followed by a drop-off back down to almost zero sales after a few days. So my strategy was to make a gimmicky sort of app that bloggers might find interesting, and then try to get someone to write about it. It’s now looking like that might be the wrong strategy to use in the App Store.
The first surprise was that the app has sold more than 50 copies each day that it’s been available, and as far as I can tell there has been absolutely no English press about the app at all yet which would be driving these sales. At first I thought that it might have been due to the app showing up in the “new apps” section in iTunes on the day it was released, but it hasn’t been new for a week now, and the sales are still keeping up. Without any press or publicity, my only guess is that people are finding the app by browsing the Utilities section in iTunes, where it currently is ranked around #70.
The next semi-surprise was that I started to receive a whole bunch of emails from customers who had purchased the app. Many of them were of the “Hey, great app!” variety, but a lot of them were from people who liked the app but couldn’t use it because it didn’t work with the cube that they had. Among other problems, it turns out that all cubes sold in Japan and many in Europe use a different color scheme than cubes currently sold in the U.S. The app would tell the user to input the “Blue face with the White face on top”, which would be impossible because the Blue and White faces are on opposite sides of those cubes. I rushed out a 1.1 update to support that style of cube (and custom user-specified styles), but the update has been languishing “In Review” for almost a week now - Apple’s system was closed for much of the Christmas week, so I’m hoping that the update will go live sometime this week.
So far only 68% of the sales have come from the U.S., meaning that a full 32% are coming from overseas, which is more than I had originally expected. The app isn’t localized at all - it’s only available in English. Localizing it would require paying quite a few translators to translate all the text strings in the app, which could get expensive depending on how many languages I wanted to support. At this point I’m not really sure how to tell whether or not it would be worth doing that, financially-speaking. I designed the app’s UI under the assumption that nobody reads any explanatory text anyway, so it’s pretty graphical and should be usable without knowing much English. It seems to be selling OK in non-English countries, and I haven’t received any emails requesting that the app be translated into a specific language, so maybe it is OK as it is. On the other hand, that’s sort of an argument from fallacy because if people aren’t buying the app since it’s not available in their language, then they wouldn’t be sending me emails in the first place. Also, a large majority of sales have been from the U.S., U.K., Canada, and Germany, where most everyone understands English (or at least the people who are buying iPhone apps). At this point I think that if I did localize the app, the first languages to tackle would be Spanish, Portuguese, Japanese and Chinese, in order to cover the largest number of potential customers.
Anyway, enough with all the blathering, let’s get to the meat of the post: the actual sales stats. Here’s a graph of CubeCheater’s daily sales, overlaid with its rank in the Utilities category in iTunes:
This graph shows a few interesting things:
- The sales were pretty consistent leading up to Christmas, at which point there was a huge jump. Right now there are only two data points after Christmas, so it’s hard to say if this is a permanent shift or if it’s a one-time fluke. I assume that it happened because a whole bunch of people got new iPhones and iPod Touches for Christmas, so I wouldn’t be surprised if the new stable sales point is somewhere in between.
- The iTunes rank stayed constant even through the Christmas spike. The rank is determined by number of downloads, so the fact that it remained the same indicates that all iPhone apps probably experienced a similar huge jump in sales (See: A Christmas iFart Explosion: 40,000 downloads - Man do I wish I had thought of that app).
And here are the sales broken out by country for the 12/18-12/27 period:
It’s interesting to see that there’s sort of a “long tail” of countries where the app was purchased one or two times, but not in the Chris Anderson/power-law sense, since the bottom 80% of the countries only account for 10% of the sales. With this distribution I could completely ignore all but the top 3 countries if by doing so I could increase sales in those countries by 20%.
Other random thoughts after one week of sales:
- The YouTube demo video has been viewed only 573 times. Given that many of the YouTube viewers probably did not end up buying the app, this means that far less than half of the people who did buy the app watched the demo video or visited the web site for the app before buying it. I had originally thought that most people would buy the app after watching the video, but it looks like this is not the case.
- It’ll be interesting to see how long these sales numbers remain consistent. On one hand, you’d expect the sales to drop off after all of the people with both cubes and iPhones buy the app. On the other hand, the installed base of iPhones is still increasing exponentially now, which might counteract that drop-off.
- I’m curious to see how the sales are impacted if the app does get any mentions on any high-profile sites. Other developers have noted large yet temporary sales spikes.
Loyal readers have probably noticed that I haven't been posting very often in the last couple of months. During the spare seconds between my job and two classes at UW, I've been working on a new iPhone app.
I'm pleased to (finally) announce that the application is complete and should be available on the iTunes App Store soon. I just uploaded it and am now waiting for Apple's approval before it goes live.
The app is called CubeCheater and is an iPhone/iPod Touch app for solving everybody's favorite 80's puzzle cube. You input the state of your cube, and it will compute an optimal (or near-optimal) solution to solve it.
It uses the Group Theory algorithm discovered by Herbert Kociemba to do the solving. I haven't tried all 519 quintillion cube configurations, but I have run through quite a few random ones during my testing and I've never seen the program give a solution worse than 22 moves (the current upper bound  on optimal cube solutions as of August 2008). On average it takes about 7 seconds to find a good solution.
The other particularly cool part of the app is that it takes advantage of the iPhone's camera and can recognize your cube from pictures you take of it, using computer vision. I was pleased with how well this turned out - if you orient the cube properly with good lighting, it recognizes the cube perfectly every time.
That feature and most of the cool animations and 3D effects are best experienced by watching the app in action, so if you're interested, head on over to the website and check out the embedded YouTube video (or view it directly on YouTube, and don't forget to click "watch in high quality").
Here are some screenshots:
So this week all of the iPhone 2G warranties expired, at least for the people who bought them during the first week. To commemorate the occasion I decided to jailbreak my phone in order to see what all the fuss is about.
Previously, I had decided not to jailbreak since I was afraid that Apple would refuse to replace my phone if the touchscreen or other features broke (as happened to about 50% of the people I know with iPhones). Now that the warranty has expired, that's not much of a concern any more. I also figured that if my phone got screwed up, I could always upgrade to a 3G model next week anyway.
Now that I have jailbroken it, I must say that I can't believe I didn't do this a long time ago. It doesn't seem to mess up the phone at all, at least if you aren't running any custom apps. But the custom apps are completely awesome. These are what a phone with these hardware capabilities was meant to run. It's too bad that Apple's official SDK is so limited and constrained - most of the cool apps will never be allowed by Apple.
I've just gotten started trying out all the apps, but I've already found several cool ones:
Rockin' the Terminal. I booted up vi but quickly realized that that was a stupid idea when you don't have a real keyboard or Ctrl and Esc keys.
Remote Desktop is probably the killer app so far. Now I can log into my home computer and use it no matter where I am in the world (with cellular or WiFi access, of course). You'd think it would be impossible to use on the small phone screen, but with multitouch zooming and panning it actually isn't too bad.
I haven't even gotten to the 'Games' section yet, but I have definitely heard good things about the NES emulator. This should be sweet..
Sko commented on the last post inquiring about a program I had a long time ago which allowed you to make various windows on your desktop transparent. It was an old-school Windows 2000 program I wrote to try out the fancy new WS_EX_LAYERED styles in Win2K:
You could drag the cursor over a target window and adjust its transparency or make it 'always-on-top':
It's extremely simple but it was pretty cool back in the day. I just tried it out and it still seems to work for the most part, but not as well on newer versions of Windows like Vista, due to the increased security that prevents processes from messing with each other.
An interesting unintended use of the program was that it could be used to discover saved passwords in '******' textboxes, since it displayed the result of WM_GETTEXT as you dragged the cursor over various HWNDs. Fortunately they seem to have fixed that vulnerability in XP+.
Anyway, here's a link to download it:
For the final project in a class I am taking we had to build a web-based disk storage system with a REST XML API, basically like Amazon S3 but at much smaller scale. The assignment was pretty cool because it was very open-ended: our servers just had to register their URLs with the professor's server and allow him to store data blocks. How we actually did it (OS, language, etc) was completely up to us.
I decided to just run my server on a computer at home, which is what most people did. I figured it would work out fine. My biggest worry was that Comcast would block a port or go down and screw me over. Fortunately that didn't happen, but there were other problems.
For about two weeks my server ran perfectly with 100% uptime, but the professor only started monitoring uptime and availability this Tuesday. Of course, on Tuesday afternoon there was a power outage at home, and my computer didn't turn back on until I got home from work and found it. I have my main computer hooked up to a UPS so it didn't go down, but the other computer was running in a closet with no UPS. Lesson learned: always have a battery backup when homework points are at stake. Also, set all computers to reboot themselves automatically after a power loss.
After I booted it back up I figured it was OK and went to bed. Of course, this happened to be the second Tuesday of the month, so Windows Update downloaded a bunch of patches overnight and rebooted, taking out the server. My process failed to start on reboot, so I had another outage all night. Normally I always set updates to "notify only" and never "automatic", but in this one case I left it on automatic, figuring that it wouldn't matter too much since it was a closet-computer that I wouldn't even log into regularly. Lesson learned: never ever ever leave the updates on automatic, they'll always find a way to screw you at the wrong time. Also, test to make sure the service comes back up properly after a reboot.
Larger-scale, I guess I learned about the importance of having geographically distributed datacenters and automatic failover, but that wasn't really a practical option in this case.
Fortunately most of the other students in the class also suffered outages as well (see graph above), so I don't think my grade will be impacted too much.
I was updating the links on the ol' resume page and realized that I didn't have a page about any EE stuff, so I decided to write one up.
My final EE project in undergrad was to build an embedded computer system from scratch, and my team decided to build a digital video camera, called "BenderCam" (Bender didn't really have anything to do with anything, other than that one guy just really liked Futurama).
Here's a picture of the final system:
The circuit board on the left has the main CPU circuit, which was composed of a Motorola 68HC11 microcontroller, a 32K ROM with the system software, 32K of runtime RAM, and 512K of auxiliary VRAM. It also has a Spartan II FPGA with some DACs that ran the VGA interface, as well as the RS-232 serial interface to a computer workstation. It's connected via an old IDE cable to the second circuit board on the right that has the CCD video sensor and another FPGA to drive the video capture.
Here's a picture of the back of the main board:
This was mostly hand wired by me, which almost caused me to go crazy since every wire had to be perfect or else the chips could all fry. The wires at the top are for the CPU and its two 16-bit buses, and the nasty mess at the bottom is the 24-bit buses for the VRAM double-buffer. If I had to do it all again I would almost certainly go with a PCB rather than hand-wiring the whole thing.
The system captured 640x480 video in black & white (we used a CCD sensor from a security camera) and displayed it on a VGA monitor. After some tricky optimizations in the firmware, I was able to get the framerate up to about 15 frames per second, though the bandwidth at that rate was too high for the hand-wiring to handle, and EM interference started to introduce random bit errors into the video stream. Here's a picture of it taking a video of us taking a picture of it:
The CCD sensor is the thing with the electrical tape all over it, to prevent light from leaking in. On top it has a lens that we cracked out of an old dead cellphone (high quality all around).
The microcontroller also hooked up to a computer via a serial connection which could be used to download new firmware as we were debugging it, as well as upload pictures back to the computer. The connection was only 56 kbps so it could transfer about one frame every 10 seconds. Here's the software after it has taken a picture of us and some random dude who jumped into the picture:
The random white and black pixels in the image are examples of the bit errors that happened at high speeds. The "washed out" vertical lines near the ceiling lights were caused by excess capacitive charge building up on the DAC, which could be easily temporarily fixed by licking your finger and using it to short out the DAC's voltage supply line.
Today while going through some old files I found an old program I wrote back in college for a Microsoft-sponsored programming contest. Microsoft was doing a big marketing push for the newly-released .NET Framework and C#, so they sponsored programming contests at various universities to promote it (hook 'em while they're young? cough). I ended up winning an original Xbox, which was also new and cool at the time. Somewhat ironically, there was a guy from Sun Microsystems at the contest who saw my program and got me a part time job there working on Solaris.
The point of the contest was to write an application that would be useful for the university, so I decided to write an instant-messaging system called CampusChat. At the time the university had no global IM system that students could use to communicate with TAs and professors, or find and collaborate with other students. My ultimate goal would have been to create a grand, unified online environment like Project Athena at MIT, but I only had a couple of months so I went with IM.
It also allowed me to finally 'correct' all of the horrible (perceived) flaws in the corporate IM systems of the day (namely AIM, MSN and Yahoo). These flaws were:
- The IM servers were centralized and under the control of one corporation; people could not run their own servers.
- The IM client software contained advertisements that had to be hacked out of the executables.
- IM sessions were not encrypted on the wire, so your dorm-neighbors and ISPs could read all the messages (this has been mostly corrected these days, thankfully).
- IM sessions were not encrypted end-to-end, so the IM provider could read all your messages (this is still not fixed today..).
- Trust and authentication were ad-hoc, with no method to determine who you were actually talking to.
- There was no way to tell if the person you were talking to had actually received your recent IMs or had become disconnected (extremely annoying back in the dial-up days).
- You didn't know if the other person was in the middle of typing a message to you or not.
- Other users would often select horrible, ugly fonts that you could not override.
- The customizability of your own font and UI themes were very limited.
- There was no plugin architecture that you could use build apps on top of the IM system's authentication and communication layers.
The (arguably) largest flaw of the corporate IM systems was that they weren't interoperable with each other at the time, and by creating my own IM system I was admittedly making that problem even worse (open protocols like Jabber and SIP did not really exist yet).
I based CampusChat around Kerberos 5, which is a distributed authentication system that can be used for secure client-to-client communication using strong encryption. All of the IT infrastructure at the University of Colorado was based on Kerberos 5, so every student and faculty member already had Kerberos IDs, which were their usernames and passwords. It was also integrated into Windows 2000+, so if you were logged into a computer with your university username, CampusChat automatically grabbed your credentials from your login session and you didn't have to type in your password again.
Kerberos allowed for the encryption and mutual authentication of individual IM sessions between users, so that you knew exactly who you were talking to, and nobody along the wire (even the IM server itself) could read the communications. I realized later that since Kerberos is based on having a trusted third party generate the symmetric keys (rather than using public-key methods), its entire security rests with the "trusted third party" – in this case the university IT department, which was arguably nothing of the sort (as far as us Computer Science students were concerned). A malicious Kerberos server could have ruined the entire security scheme.
Once you logged into a CampusChat server, the main 'Buddy List' window looked like one of these (all screenshots are using the 'chess' theme):
The screen on the left is of a server in "community mode", where users can see all of the other people who are logged into the same server and the public chat rooms that are available. This mode was designed for individual classes or departments – a professor could set up a server for his/her students to use for collaboration, allowing students to find each other and their TAs during 'virtual office hours'. This mode is contrasted with 'classic mode', which is on the right, and behaves just like AIM or MSN, where you have lists of 'buddies' that you maintain, and you can only see the online status of the people you have explicitly added. This mode was designed more for university-wide servers which everyone could log into at once. The controls on the bottom allow you to add buddies and create public or private chat rooms. The blue slider at the bottom of the window allowed you to adjust the transparency of the window and set it to be "always on top".
IM windows look like this:
The first thing they do is initialize a secure encrypted connection with the other user. At the bottom of the window the status bar lets you know that all of your IMs have been received by the other party (or it lists the number of outstanding messages for which an ACK has not been received). It also tells you if the other person is currently typing, and has the transparency-slider control. The "Direct TCP connection" button allows you to establish a direct connection to the other user, in order to cut out the IM server from the conversation (for speed, as well as to prevent malicious servers from logging the timing and frequency of your messages).
The Text Settings dialog allows you complete control over all of your text. You can use any CSS styles you want on your text, and you are also given the ability to override your conversation partner's CSS text styles if you don't like them. For example, if you were to use the CSS string "text-align: right; background-image: url(http://www.google.com/images/logo.gif);", you would get this:
CampusChat also supports Unicode (natively, since it is written in C# and Managed C++), which allows you to converse in any language (AIM was infamous at the time for not supporting Unicode):
Multi-user chat windows are pretty similar to IM windows, though users have less control over various settings:
CampusChat supported an extensive plugin API, which you could use to modify the base client software and build your own applications on top of the secure connection. It just required implementing a specific C# interface and plopping your DLL into a specific folder. Complete .NET objects could be easily sent between clients using simple function calls (they were serialized to binary form, compressed, encrypted, and sent out automatically).
To keep things simple, I implemented a lot of CampusChat functionality as plugins, such as file-transfer, away-messages, directory lookups, speech recognition, and text-to-speech. The away-message functionality was particularly cool because you could write your own away-message provider that allowed all kinds of fancy logic about which specific people to send the messages to, different messages for different people, and so on. To demonstrate the flexibility and power of the API I also created a full-featured chess game as a plugin (only requiring a couple hundred lines of code):
Alas, in the end CampusChat died a death of neglect after the programming contest and was never widely adopted at the university. It still works great, but you can only use it if you have a valid Kerberos 5 account on some domain, which I no longer do. I've uploaded the ZIP file here for posterity:
I'm the proud new owner of the most suspicious-looking gift certificate ever:
Despite the fact that it's already expired and the amount has been crossed out multiple times, it's supposedly legit. We'll see if the golf course accepts it..
I won it in the weekly office happy hour competition. This week the challenge was to write an implementation of a function with the signature "void ArraySort(int array, int length)" that has O(1) memory usage. This was my entry:
void ArraySort(int _array, int _length)
mov eax, [_length]
mov eax, [_array]
mov eax, [qsort]
add esp, 16
mov edx, [ebp-8]
mov ecx, [ebp-4]
mov eax, [ecx]
cmp eax, [edx]
mov eax, 1
cmp eax, [edx]
mov eax, -1
xor eax, eax
I particularly like this implementation because the code for the qsort callback is embedded inside the ArraySort function. I was sad that not everybody else appreciated the sublime beauty of this as much as I did.
Today I got my dead-tree copy of my first 'real' published magazine article. It's in MSDN Magazine and is about the new UI in Microsoft Office. It made the lead article for the February 2007 issue, and they even used a diagram I drew on the cover. Sweet! 🙂
The article title ("RibbonX API: Extend the 2007 Office System With Your Own Ribbon Tabs and Controls") was obviously written by editors, but that's OK 😛
Update:It's up on the MSDN website now:
Recently I've been a "guest writer" on Jensen Harris' popular Office UI Blog (popular in the HCI and MVP communities, at least :P).
If you're curious about what I work on all day, check out my posts:
They're pretty targeted to 3rd-party ISVs that leverage Office 2007 as a platform, so if you aren't one of those then the articles probably won't make much sense (and will probably sound like complete gibberish if you aren't a programmer).
There probably won't be any new posts on that blog for a while (due to the holidays), but in a few weeks there should be more.
I also just finished up writing an article on RibbonX for MSDN Magazine, so if you're a subscriber make sure to check out the upcoming issues! Once it's published I'll grab a copy and get a pic up here.
Here's a video (below) of a few of the more interesting monome apps I've made so far (see this post for an explanation of what a monome is).
- "Grid" game: I haven't thought of a better name, but this game is sort of like Othello or Go. Players play as "light" or "dark" and try to capture the opponent's territory by toggling his/her pieces and then capturing any surrounded squares. It's interesting to play at first, but after playing several people without finishing a game, we determined that it's probably not actually winnable as long as both players always make intelligent moves. But, interestingly enough, a "greedy" AI that plays against itself will often end up winning (and losing), as long as it doesn't get stuck in an infinite loop.
- "Raindrop": this is a raindrop ripple simulator. You can create ripples by pushing buttons - the more you push, the bigger the ripples. It's pretty cool.
- Pong: the classic. The resolution (8x8) is a little low, but it actually works pretty well since the computer simulates the board at higher resolution. The main problem I see with Pong is that each player has only 2 inputs (up and down), so it's not using the full power of the 64 buttons, which it seems like good monome apps should.
Here's the YouTube video:
The best part is that it doesn't come with any software in the box, no CD or even a slip of paper with a download URL on it. You have to write your own software from scratch to use it. How awesome is that? It pops up as a USB serial port when you plug it in and it uses a dead-simple 2-byte protocol so it's pretty easy.
So what does it do? It doesn't do anything ... in particular. It does whatever you make it do. It seems that most of the apps people have written so far deal with using it as a sort of MIDI sequencer (see this video for an example).
I have a ton of ideas for cool little games for it, but I'm not yet sure how well they'll work. The main problem I see is that there are only 2 states for the LEDs: on or off. So even a simple 8x8 game like checkers wouldn't work, since you need at least 3 states (5 with kings). "Blinking" could be used as a third state for those kind of games, but I think it would get kind of distracting.
I'm going to start off by making an Othello/Go-type game and a Pong game and go from there.
If I played WoW it could be useful as a gigantic macro pad or something like that, but I don't (fortunately?).
Part of my justification for getting a new iPod would be that it would have video support, and I could use it to watch recorded TV shows while I'm on the bus or waiting in line somewhere. I figured that somebody in the world must have written some software to automatically synchronize TV shows recorded on a Media Center PC to an iPod Video. I mean, right?
Apparently not. Or at least I couldn't find any software to do that, free or commercial. Sure, there are various tutorials for converting MCE videos to iPod-compatible files, but they all involve manually running 3 different programs and then importing the video into iTunes by hand. There must be an untapped marked for an MCE plugin that automatically converts and syncs TV shows to an iPod. Somebody could make a killing here!
In the meantime, it looked like I would have to write my own program to do this. These were the requirements I had:
- Plop the iPod into the dock
- Go to bed
- Wake up, the iPod automatically has all the TV shows I recorded the day before
I wrote a small C# program that does the following things:
- Check if I have deleted any recorded shows from the Media Center PC. If so, delete the iPod versions out of the iTunes library.
- Find all of the new TV shows that the MCE recorded since last syncing to the iPod.
- Take each new show and convert it from a .dvr-ms file to a .mpeg2 file using DVRMSToolbox.
- Convert the .mpeg2 file to an MPEG-4 file using ffmpeg, shrinking the video to 320x240 at 512 kbps.
- Delete the temporary MPEG 2 file.
- Save the .mp4 file into the iTunes video library folder.
- Force iTunes to update its library database and sync to any connected iPods (using iTunes Library Updater).
Next I created a Scheduled Task to run MCEiPodSync every day at 3:00 AM:
Now all I have to do is plug in the iPod and go to bed. Sweet! Here is a pic of the iPod playing Full House (it was on while I was testing):
Here's a link to the source code for my little program if anybody's interested: MCEiPodSync.cs. You just have to switch the const strings at the top to point to the correct path to your Recorded TV and iTunes library folders.
Amber commented on a previous post, expressing interest in playing the game I mentioned there. Here is a link to download it:
You will need to have the Isis Game Engine installed in order to play. Unzip bruto.zip and double-click bruto.iss to launch it (if you didn't use the Isis installer, run bruto.iss with the 'ivmconsole' program).
You control the dragon and must protect your hometown from marauding invaders. Fly around using the I, J, K, and L keys. Spacebar breathes fire, and the F key sucks in air in order to shoot fireballs (if you don't like those controls, you can edit dragon.iss in notepad and change them). You win after defeating 20 ships, or you lose when your town and castle are destroyed.
If you don't want to download the game but still want to see it in action, here is a WMV video of me playing. Note that the video has no sound because the game has no sound. Here's a low-quality YouTube copy of the video:
A couple of people were curious about the game engine behind Osiris, so I have written up a little page about it:
There's not much on that page yet, but it has an introduction to IsisScript and a couple of sample games. There are also links to the installer as well as the source code if you are interested in checking it out.
I've been asked a few times for a copy of Expedition: Osiris, an educational computer game I worked on while in college. Unfortunately some of the images of Egyptian artifacts that are in the game are copyrighted by the university, so the game cannot be distributed publicly. But, I did get permission to create a "public domain" version of the game, as long as all the artifact images were obscured. Today I finally got around to doing it. Here are download links: (they are about 17 MB each)
The system requirements are pretty modest: a 1 GHz processor and a 32 MB video card should play the game just fine.
Here is a medium quality WMV video of me playing the game for a few minutes: Osiris Video. It's a big file but it should stream OK. Here's a low-quality YouTube copy:
The purpose of the game is to teach the basics of a freshman 'Archaeology 101' class. You play the role of a college professor who organizes an Egyptian dig and are supposed to learn how to do the following things:
- Acquire funding
- Create a team of graduate students, specialists and local workers
- Manage the digging process to maximize efficiency and minimize artifact breakage
- Fend off attacks from mummies, crocodiles, scorpions, thieves and evil genies
- Manage team morale and energy while keeping within the budget
- Interpret your findings
- Publish your results in respectable journals to increase your prestige
Here are a couple of screenshots:
Setting up the team
Managing the dig
Have you ever looked at the FSAA settings in the control panel for your graphics card and wondered what the real visual difference is between them?
I was curious myself and decided to do a mini benchmark test. I pulled up a game I wrote a while ago called "The Adventures of Bruto" where you fly around as a dragon and fend off a naval attack. All of the graphics in the game are vector images, so it is a good visual test case for FSAA:
I took screenshots of the game at each FSAA setting level for a comparison. Here are closeups of the castle at 0x, 2x, 4x and 8x:
Overall the screenshots seem to confirm the idea that "more is better" when it comes to FSAA, but once you get past 2x the improvements don't seem to be that noticeable. I'll probably leave games on 2x or 4x and bump up other settings like model/texture detail if I need to make a tradeoff.
A few weeks ago I was at the mall and I walked by a LEGO Store. I had heard of these, but I did not realize that there was one nearby. Naturally, I had to go in. When I came out, I had $200+ worth of LEGOs, and a membership in their "Loyalty Discount Card" program.
The most interesting thing I got was a Mindstorms kit. The Mindstorms kit lets you build little LEGO robots out of electric motors, wheels, gears, and things like that. Somehow I missed out on them when I was a kid, but I have them now.
I always wanted to make a wireless rover bot that could drive around the floor and take pictures of things. I was able to make a robot like that in college, but it had a bunch of wires hooked to it for power and control, so it wasn't as cool as it could have been. Now, with the Mindstorms kit I realized I had everything I would need. I could build a little robot out of LEGOs and attach my cell phone to it. The cell phone would direct the robot and send pictures back to my laptop, where I would be controlling the whole thing.
It ended up being more difficult than it sounded, primarily because the LEGO computer could only communicate via infrared, and it was a proprietary protocol (not IrDA), so the IR port on my cell phone would not work. I solved the problem by ripping the IR PCB out of the Mindstorms transmitter, attaching it to a handy Bluetooth serial port, and hooking it up to a RC car battery pack. Unfortunately the IR transmitter required 9V and the Bluetooth receiver required 5V, so I had to add a regulator into the mix, but it turned out OK:
Now my phone could communicate wirelessly with the LEGO controller over Bluetooth. Luckily the protocol had already been previously reverse-engineered by a Stanford student with far too much time on his hands, so I didn't have to do that too.
The next thing to do was to build a robot that could house the battery and hold the cell phone up. I wanted it to be able to turn around and rotate in place, so I came up with a 3-wheeled design:
It ended up being a bit top-heavy, but it works pretty well.The last thing to do was to get a video-conferencing program to run on the phone and transmit video back to my laptop. I figured this would be the easiest part of the project, but it ended up being the most difficult, because I had to write my own by hand. I was shocked to find that there were no Pocket PC video conferencing programs that worked with Windows Mobile 5.0 over WiFi. Microsoft Portrait was almost exactly what I needed, but unfortunately it had not been updated in several years and did not work with my phone's camera.
I started from an SDK sample that captured JPEG images and made a little program that sends a stream of images to a PC over WiFi. It's a bit slow since it doesn't use a real video codec, but it's still surprisingly fast. It updates at about the speed of a USB webcam. Here's a screenshot of the PC half of the software:
Finally I had everything in place and was able to drive the robot around and see where it was going from my computer. Awesome!
Here is a video of me driving it around:
Last weekend I became distressed that the 500 MHz processor in my cell phone (i-mate Jasjar) was going to waste for most of the day, so I decided to do something about it. I searched around a bit and came across PocketSNES, a Super Nintendo emulator for Pocket PCs (in a strange twist of fate, PocketSNES is maintained by somebody who works for the same company I do). When I was a kid, I was (still am?) a huge SNES fan, so this sounded perfect.
Unfortunately PocketSNES was built for PocketPC 2003 (not 2005), and was hard-coded everywhere for portrait-mode 240x320 screens. After fixing a lot of bugs and recompiling with the latest SDK, I was able to get it to work in 480x640 mode:
Now it was more or less usable, but it was very slow. I debugged it and discovered that Windows Mobile 5.0 was using an emulated framebuffer for GAPI games, which was slowing everything down considerably. After poking various memory addresses (and crashing the phone several times - so much for Windows CE memory protection..), I found that the video memory for the Intel PXA embedded video begins at virtual address 0xA87AA000, and is laid out linearly (480x640x16). Replacing the GAPI code with direct video memory access and turning on compiler optimization made PocketSNES run quite fast (even the sound worked pretty well).
Now the only problem was that it was a huge pain to play using the little on-screen keypad. Using the phone's keyboard didn't work too well either since it had a hard time accepting multiple simultaneous button presses. After some more searching, I came across the Chainpus BGP100 Bluetooth gamepad (yeah, they need a new name for it):
It looks hideous because it's designed to fit around a cell phone (my phone was too big). It was surprisingly easy to set up and associate it with the phone using Bluetooth. The software for it, on the other hand, was very poorly implemented and translated. It had also not been recompiled for Windows Mobile 5.0 either. As a result, there was almost a 1-second delay between a button press on the gamepad and when it was recognized by the game (this was mainly because PocketSNES was using 100% of the CPU). Unfortunately the source code was not available, so I had to re-implement its functionality by hand in order to fix that problem. The gamepad implements the Bluetooth Serial Port Profile (SPP), and it sends sequences of 3 bytes for each button press & release event, so it was actually extremely easy to work with. I just had to create a virtual COM port using the Bluetooth control panel, open the 'file' COM3 and read bytes from it when it was input time.
When that was all done, I was able to play at a comfortable distance from the phone:
This should be very useful for boring meetings at work 🙂
Here's a video: