Posts from the “Software Development” Category

HexDefense

Intense, arcade-style tower defense for Android

The Story

HexDefense started as a class project for a mobile prototyping lab I took while at Carnegie Mellon. The lab required that apps be written in Java on the Android platform, and I figured it’d be a good opportunity to try writing a game. I’m a big fan of the tower defense genre and I’ve been heavily influenced by games on the iPhone like Field Runners and GeoDefense Swarm. From the outset, I wanted the game to have arcade style graphics reminiscent of Geometry Wars. That way, I figured, I wouldn’t have to find an artist to create the sprites, and I could focus on explosive OpenGL particle effects and blend-based bloom.

During the fall semester, I collaborated with Paul Caravelli and Tony Zhang on the first iteration of the game. I had the strongest graphics and animation background, so I focused on the gameplay and wrote all of the OpenGL code behind the game. I also created most of the game model, implementing the towers and creeps and creating actions with game logic for tower targeting, attacks, projectile motion, explosions, implosions and other effects. Paul contributed path finding code for the creeps based on breadth-first-search and created interfaces for implementing in-game actions based on the command pattern. He also contributed the original implementation of the grid model and worked on abstract base classes in the game model. Tony created the app’s settings screen and linked together activities for the different screens of the application.

At the end of the fall semester, the game was functional but unrefined. There were no sounds, no levels, and I’d only created one type of enemy. After the class ended, I talked with Paul and decided to finish it over my Christmas break. Paul was too busy to continue working on the app, so I continued development independently. I worked full-time for four weeks to deliver the level of polish I was accustomed to on the iPhone. I refined the graphics, tested the app across a variety of phones and added fifteen levels. I also added 3D directional sound, boss creeps and wrapped everything in a completely new look and feel. People say that the last 10% is the 90% of the work, and I think that’s particularly true on Android – there are minor differences across devices that make writing a solid game a lot more work than I expected.

The game was released at the end of January and has been well received so far. I created a lot of promotional art and setup a website with gameplay footage and press resources, and the game has garnered quite a bit of attention. It’s been featured on the front page of the Android marketplace and has a 4 1/2 stars. It’s rising in the “Paid Apps” rankings and is currently the #16th most popular game on the Android platform!

Lessons Learned:

I’ve learned a lot about the Android platform developing HexDefense. A couple of tips and takeaways:

  1. Let the OpenGL view run in CONTINUOUS mode. Nothing else (timers, threads that trigger redraws) will give performance close to this.
  2. Write all of the game logic so that it can advance the model by an arbitrary number of milliseconds. Because multitasking can cause hiccups in the game framerate, this is _really_ important for a smooth game.
  3. OpenGL textures are not numbered sequentially on all devices. The original DROID will choose random integer values each time you call glGenTexture.
  4. There are numerous drawbacks to using the Java OpenGL API. If your game needs to modify vertex or texcoord buffers every frame, you’ll have to accept a performance hit. The deformation of the grid in HexDefense is achieved by modifying the texcoords on a sub-segmented plane, and passing the data through a ByteBuffer to OpenGL is not cool.
  5. The iPhone’s OpenGL implementation is at least 2.5x faster, even on devices with half the processor speed. An iOS port of HexDefense is in progress, and the game runs twice as fast on an original iPod Touch as it does on a Nexus One. There are a lot of reasons for this, but it seems that drawing large textured quads has greater speed implications on Android devices.

Layers for iPad

I started working on Layers for iPad the morning apple released the iPad SDK. I’d been looking forward to the release of the iPad for months, and it made sense to make a dedicated version of the app. I’d always had a difficult time drawing on the iPhone’s small 3″ screen. The iPad seemed like a perfect tool for professional artists–a digital sketch book you could carry anywhere.

The iPad’s larger form factor also raised new interaction questions. It was too big to shake, so the “wrist flick”-triggered menus in the original Layers app were out. It had more room for contextual information-toolbars wouldn’t significantly limit the size of the canvas viewport. The iPad also created new opportunities for community. It’s large screen was so good for showing off art that it seemed natural to allow people to post paintings and browse and comment on others work within the app. From the earliest phase of design, the focus was on building a community around the art people created on the iPad.

I spent about three weeks designing an interface for the iPad app, prototyping and fleshing out different screens of the app in Fireworks. Since I knew I would be doing the entire app myself, I didn’t bother creating storyboards using the individual interface mockups.

I like to write code during the design phase when I work on personal projects: a few hours of design, a few hours of code, repeat. It helps to step away from the designs every few hours. I started moving code from the iPhone version of Layers over to the iPad on day one, and a couple big issues became obvious in the first few weeks:

1. The display / memory ratio on the iPad makes it hard to keep display-quality images in memory. The iPhone version of Layers kept six 512×512 OpenGL textures in memory, but the iPad version isn’t able to keep six 1024×1024 images in memory. Fail!

2. Saving the image for each layer took more time (roughly 4x more, since there were 4x as many pixels) and caused the app to be terminated early when sent to the background.

3. Some procedures in Layers, like undoing a “Shift Layer” operation, took too much memory when the images were scaled up.

Unfortunately, I didn’t have early access to iPad hardware, so I didn’t know that #1 and #3 would be an issue until the app was actually live on the store. I got a ton of emails the week the iPad went on sale, and I skipped an entire week of class to fix the problems. The solution was a much smarter method of memory management that allows layers and parts of the undo stack to be paged to disk when the app receives memory warnings. It brought some major speed improvements to the iPad version, and I’ve since been rolled it back into the iPhone version.

Layers for iPad consists of 22,000 lines of Objective-C code, about 10,000 of which are shared with the iPhone version. The community component of the app is built in PHP and mySQL, and uses HTML5 and advanced Safari CSS 3 markup to create a convincing and “native” experience within the app. My experience building the community website was very positive. CSS 3 support on the iPad is great, I think web views are the best way to deliver native-looking and richly customized interfaces. You can even specify your own fonts. It’s beautifully fast. Had I chosen to deliver content via XML and render it all in custom UIViews, there’s no way I could have completed the app in three months.

In the first six months after its release, Layers for iPad was downloaded about 10,500 times. The Layers Gallery, the community built around content generated in the app, hosts thousands of paintings. The app was featured on the front page of the App Store during the week of April 28th, and was reviewed by TUAW and MacWorld twice! It was featured in Incase’s 2010 advertising campaign and billed as the favorite painting app of Ron Radziner. The Layers for iPad website has also received recognition for its clean, refined design on OneExtraPixel”, Designer Daily and Web Design Tuts+

After Layers was released for iPad, I worked with MEDLMobile in San Francisco to develop the app “Drawing Step by Step with Walter Foster” using the Layers painting engine to emulate realistic pens and pencils. During it’s first week on the store, that app was ranked #1 in Productivity.

Silly Story Maker

Last spring, I worked with Demetri Miller to create Silly Story Maker, an adaptation of an educational, sentence making soundboard for the iPad. With beautiful graphics and multiple voices to choose from, Silly Story Maker allows you to create simple sentences by combining thirty basic words and phrases.

Since the app is designed for kids, we wanted it to be highly responsive. The characters bounce as the app speaks their names and the entire interface is colorful, tactile and interactive. Demetri and I built the entire app using Apple’s standard audio APIs and Core Animation, which made this interactivity easy.

A few weeks after it’s release, Silly Story Maker was the #2 education app in Australia!

Maya Distributed Rendering Tool

Abstract: The Maya Distributed Render Client and Slave system allows you to specify a render job on one machine and start it on a set of networked “slave” machines. It also allows you to view the completed images and save them to a folder on the local hard disk. The system was built in Cocoa for Mac OS X and uses Rendezvous networking technologies for automatic slave discovery. It was designed for a relatively slow network of machines running Alias Maya 6.0. I haven’t tested it with earlier versions, and versions newer than 6.0 have this functionality built in.

Installation: The Maya Distributed Render Client is a relatively straightforward application. Drag it to your Applications folder, and make sure limitations are not set which would restrict users from running it. A copy of Maya is not required for the client machine, because the client will not use itself as a render slave. (The Idea here is that you can continue modeling while the scene is rendering.)

Setting up Slaves: The Maya Distributed Render Slave runs on the rendering machines, and handles job requests. When a request is received, the slave transfers the necessary scene data and starts the render in Maya. Drag the slave application to your applications folder and make sure a licensed copy of Maya (must be recent enough to open the file) is installed on the machine. Launch the slave application and enter a name for the machine in the edit field. Do not select an images folder. Press the Start button to make the slave available on the network. If the machine will be used for rendering on a regular basis, you might consider making the application a startup item via the Accounts preference pane.

Rendering a Scene: To render a scene using the Maya Distributed Render Client, run the application and select the scene file. If your scene contains textures or source images, you must also select a “textures directory”. This textures directory will be copied to the remote slaves along with the scene file. Once you have selected a scene file and the textures folder, enter the start and stop points for the animation. The client needs to know which frames you want to render, in order to distribute them evenly among the slaves. All other render settings (such as image size, format, and quality) should be set from within Maya using the Render Settings window.
  Once you have entered all the necessary information, select the slaves you   would like to use from the list in the left half of the window. If you don’t   see any slaves, see the troubleshooting information below. Once you have slaves   selected, press the Render button. Note that the “remote slaves” system is   not completely finished. It may not work under certain circumstances (and that   url that’s in there? not a real slave ;-) – sorry). Chasing arrows will appear,   but will not move (I got lazy). When all of the data has been sent and the   remote renders started, the Rendered Images window will appear and allow you   to copy the completed images back to your machine. The list of images updates   once a minute, so… be patient.

Client Troubleshooting:
  1. When I press the render button nothing seems to happen. The slaves do not     begin the render, and the images window never comes up.
  Open the console and look for an error message being sent when you press the   Render button. If you have done something bad (like force-quitted the application   while the socket connections were still open), you may need to log out and   log back in to clear the port. If this doesn’t work, try restarting the render   slaves. (sockets are VERY messy things – If something unexpected happens and   the connection isn’t properly closed down, any attempts to re-open it will   fail)
  2. I don’t see any render slaves in the list.
  Make sure there are computers on your local network running the Maya Distributed   Render Slave application, and that you have pressed the “Start” button   in each of these. If you still aren’t seeing any (which would be very odd),   check your network connection and/or restart. The Maya Distributed applications   use Rendezvous Networking for automatic socket discovery, and that usually   doesn’t fail.

Slave Troubleshooting:
  1. When the slave receives a job, a window appears asking me to find Maya.
  The slave doesn’t know where Maya is on the disk, or doesn’t know which version   to use. Select it and continue. To prevent the window from coming up again,   keep Maya running in the background.
  2. The slave machine renders, but the images do not appear in the list on the   client machine.
  This is what the images directory option is for. By default, the images are   saved to /private/tmp/MayaDistributedProject/http://www.gotow.net/creative/attachments/mayadistributed/, but in some special cases   (permissions problems, mostly) that has not been working. Find where Maya has   put the images, and the next time you launch the rendering slave select that   folder as the images folder. When the client requests the list of rendered   images, the slave will return the contents of that folder instead of the default.

Well, that’s about it! I covered everything pretty briefly. If you have any questions about the Maya Distributed system, feel free to email me. Why does the menu read “Picture Sharing Browser”? Well, I developed this off of an Apple Developer example, which used Rendezvous to do picture sharing. First time                   I’ve used rendezvous…

Version History:
 
  1.0 = The current version. Does everything I need it too. If I end up getting   a lot of requests for improvements, I will probably make another version.

BuddyTracker

Abstract:

Abstract: Buddy Tracker is a utility for Mac OS X which allows you to monitor the status of your iChat buddies. Ever wanted to know exactly how long your friends were online while you were gone? What about their away messages? Buddy Tracker records all this information and allows you to view it in an attractive graph format. For more detailed reports on your buddies, you can export buddy history to an HTML file. These provide information about average buddy availability and total online presence time, as well as breakdowns on individual buddies. Want more? BuddyTracker allows you to create pending buddy messages which get sent when your buddy comes back to their computer (or goes away!). You can also edit your profile using BuddyTracker, something that iChat won’t let you do unless you have Mac OS X 10.4.

Getting Started:

Download BuddyTracker by clicking the link above if you haven’t already. Mount the disk image and copy the application to your Applications folder. Run BuddyTracker, and take a look at the window that appears. If iChat isn’t running, the window may appear empty or your buddies will show a “?” to the left of their names. Start iChat and login to your AIM account. BuddyTracker should now display your buddy list and a status icon should appear beside each of your buddies. Let’s talk a little more about that window. To the right of each of your buddies is a long bar. By default, the bars graph the presence of your buddies over the last ten minutes. If you watch for a few minutes, the graphs should begin to build (the newest data fills in at the right). Hovering over a one of the graphs will allow you to read your buddies’ away messages. You can change the time interval displayed using the popup menu at the top of the window.

For a more accurate representation of your buddies’ status history, you need to open a graph window. Select two or three of your buddies and press the graph icon at the top of the window. A new window will appear with your selected buddies on the left. You can drag more buddies into the window from the main window if you want. The graphs of their availability are now longer and fill the right side of the window. You can change the window of time you are viewing using the green slider at the top of the window. Dragging either of the endpoints allows you to narrow the window of time.

HTML Research Prints:

The detailed graph window also allows you to save recorded buddy data to a folder of HTML files. This can give you a much nicer presentation of the data and will also allow you to print tracking results for research purposes. To generate an HTML version of your results, use the green bar at the top of the window to select a time frame, and then press the Research button. The research button looks like a beaker and is located in the upper left part of the window. A window will appear prompting you for a destination folder. You should probably create a new folder and select that. BuddyTracker will create three HTML files and an images folder within this directory.
Once you select a folder, BuddyTracker will create the files necessary to view your data in HTML. In the Finder, locate the folder you created and open the “buddies.html” file within it. Here you can see a more detailed analysis of each of your buddies. Each screenname is displayed on the left, with a graph of their availability and a time analysis on the right. Below are average times. Graphs and time sample information is available the other pages. You can access these through the menus at the top and bottom of the page.

Pending Messages:

To create a pending message, select a buddy in the main window and click the pending message icon. This looks like an iChat bubble with a green status dot beside it. A window will appear allowing you to type a message to this person. You can change the selected buddy by typing their screen-name or real name into the field in the top left of this window. If you select repeating, this message will not be deleted after it is sent, and will be sent every time the buddy’s status matches the criteria. This can be great if you’re trying to annoy someone. When you’re done preparing you message, click the Save button. The sheet will close and you’ll see a list of your pending messages. To open this window later on, press Command-2 or select Pending Messages from the Window menu.

Changing Your Profile:

Changing your Profile: Prior to Mac OS X 10.4 (iChat 3.0), it was impossible to change your profile from within iChat. BuddyTracker allows you to do just that. Open the profile editor by selecting Change my Profile from the File menu. You can insert links and smileys, and use custom fonts and colors. BuddyTracker also checks spelling as you type.

What isn’t Working:

BuddyTracker is a work in progress! There are several incomplete features and toolbar items which don’t currently work. The magnifying glass and save functions in the detailed graph window aren’t done yet, and the “Change my Icon” feature in the file menu isn’t working under Mac OS X 10.4. It should still work under previous versions of the Mac OS X, and allows you to use an animated gif as your buddy icon (iChat only does single frames!)

Support?

If BuddyTracker isn’t working for you, email me! It’s freeware, and I can’t guarantee support — but I’ll do what I can.

Unstoppable Progress

Panther Note: Unstoppable Progress is compatible with Mac OS X Panther (v 1.3). If you are upgrading to Panther, you will need to download the new version of Unsanity’s Application Enhancer for 10.3.

Movie: Click here to see a QuickTime movie of Unstoppable Progress in action! (4.2 MB)

What is this?
Unstoppable Progress is a hack we created for the MacHax Best Hack Contest, part of the MacHack Conference in Detroit, Michigan. The contest is really very simple. You program a hack, present it, and vote for it as many times as you can. The ballots are tallied and the winners receive prizes during the banquet on the last day of the conference.

So what exactly is a hack? Well, we’re not talking about hacking into other people’s computers or stealing corporate information. If this hack destroys anyone’s computer, it will be yours. Hacks for the MacHax contest can be anything, so long as they meet the following two criteria: a) the hack must be completely useless and b) it must be extremely funny – or at least, well presented.

In keeping with the “Unstoppable” theme of this year’s MacHack conference, Unstoppable Progress causes progress bars to become “unstoppable”. What would a progress bar do if it never stopped? Overflow into the window, of course. Install it and see it for yourself, or at least watch the movie above to see the effect.

The source to Unstoppable Progress is included as part of the download available above. It’s a Project Builder project, and requires the Unsanity Application Enhancer SDK. It’s pretty messy, but we commented it as best we could. Poke around and have fun!

Requirements
In order to use Unstoppable Progress, your system must be able to meet the following list of requirements:

  • OS X (1.2.6 is best, the hack has not been tested under other versions). Unstoppable Progress is compatible with Mac OS X Panther (10.3).
  • “Oodles of memory”
  • At least one Carbon application with a progress bar (The Finder, Photoshop, Stuffit, Classic Startup
  • The Application Enhancer from Unsanity . The easiest way to get this is just to install one of Unsanity’s products – Mighty Mouse, WindowShade X, etc…

For those of you who attended MacHack and saw this hack presented, rejoice! This is not the same version that was on the MacHack CD. This is version 2.0, revised and um.. no longer crashing. We strongly recommend using this version.

Installation Information:
To install Unstoppable Progress on your computer, do the following:

  1. Confirm that it meets the requirements outlined above.
  2. Download it via the download link at the top of this page.
  3. Drag the Unstoppable Progress.ape file to Home > Library > Application Enhancers (if there is no folder by that name, you still need to get the Unsanity Application Enhancer. See the Requirements section for details).
  4. Log out and log back in.
  5. Run a Carbon Application and make it show a progress bar. (i.e. empty the Trash, unstuff a file, start a lengthy Photoshop filter). Ta da! Sit back and watch the waves. The water will disappear after a while, and you can continue using the application. If you get impatient, you can use the Escape key to end the water effects early.

I’m Seasick!
To uninstall Unstoppable Progress, do the following:

  1. Open the Home > Library > Application Enhancers folder and remove the Unstoppable Progress.ape file. You can move it to anywhere you want.
  2. Log out and log back in for the removal to take effect.

Version History:

  • 2.0 = Actually works. Water is now translucent and control of the event loop is returned to the application after the displaying is done.
  • 1.0 = This was the original version presented at MacHack. It was mean, it was messy, but it worked in three applications.