The first SproutCore interview I attempted with Eloqua’s Matt Grantham and Ryan Mudryk went well and it acquired a lot of viewership. Knowing that, I decided to test the waters again and try a second SproutCore interview this time with Michael Harris who created the SproutCore Sudoku game. Mike is consultant and local here in the Washington, DC area, so he and I met one day during lunch to discuss his game and SproutCore itself.
Frozen Canuck: Mike, first I’d like to congratulate you on your SproutCore Sudoku game. It was very well done. Since you’ve released your Sudoku game I’ve noticed that you got put on the HTML5games.com web site and had the game added to the Google Chrome web store. What has the general reaction been like since you released the game to the public?
Michael Harris: It’s been pretty good. The HTML5 thing was completely unexpected. I had no hand in that. It just got picked up. So I was pretty psyched about it. You know, HTML5 is kind of a nebulous concept, but technically it is HTML5 because is was using the HTML5 manifest for offline caching which worked almost flawlessly.
The biggest validation of what I did was, through various channels, Google basically saying that they’d like me to put Sudoku on their web store. This is because at the time they did not have any Sudoku submission, I think. It’s really easy to get an app into the Google Chrome web store once you have the code — almost trivial. There was definitely usage before my game went onto the web store, which was good, and I got some good feedback from people. There have been a lot more submissions to the web store for Sudoku, so I will have to expand what I have. I’m probably going to do a free version that has advertising and will allow you to play the easy games.
One of the things I plan on doing is adding more features that will really make the paid version worth the money. When you look at Amazon.com and look at a Sudoku book there a bunch for around ten dollars for four hundred puzzles, maybe. My game will generate hundreds of thousands of games, so I actually think its worth the value, but if the competition is free in one form or another then I’ll have to change some things.
FC: Sure, that makes sense. Let’s go back a little bit. What was it that got you writing your Sudoku app in the first place?
FC: [Laughs] Right. So it sounds like there were a lot of challenges?
FC: In the case of SproutCore itself, what were the main components behind putting it together?
MH: Traditionally I am a server-side developer, specifically in the Java world, and I come frameworks like Spring. SproutCore is an application framework, and there was a high degree of comfort for me working in another framework. The M-V-C nature of SproutCore really lends itself to almost everything, but especially for problems like building my Sudoku application. For instance, you have the Sudoku meta-data record at the top level and then you just have 81 cells — that’s essentially it. When you update a value on a cell the KVO and bindings infrastructure cause all the hints to be recalculated, and because of the MVC nature of SproutCore, meaning the view elements are bound to the data elements, everything just updates. SproutCore as an MVC framework lends itself to this sort of problem really well. As they say, there’s no glue code. What they really should say is the glue code is the framework, specifically the binding mechanism. It worked really well.
FC: So at any time when using SproutCore, did you have to do things against the grain or things that were a little bit different?
MH: Yeah. Previously I always built views programmatically and did things such as, if I had a cell and I wanted to switch from showing the cell’s value to showing the cell’s lists of hints, I would have a hints view and a value view as child views of the cell and I would swap them out with the
isVisible property. That wasn’t performing very well so I reached out for some outside help [Laughs, points at me]. What it came down to was recognizing that this game was running in a browser, and browsers are really good and
innerHTML replaces. So the answer to solving that performance problem was to render the cell’s value and hints within the cell view itself using the
render method. This as opposed to having programmatic child views that got swapped based on certain conditions. Therefore the cell view is just one view with a
render method that branches based on the state of the data in the cell.
One area that I ran into difficulty was the data store. The data store is really similar to an ORM framework, and what they expect you to have is a parent record with child records. In Sudoku the cells don’t have their own lifecycle and are just a small piece of data that are never going to be saved separately. What is really needed is something called a “component” that you find in the Java Hibernate framework. A component is a separate object that doesn’t have its own lifecycle; it’s just part of the parent object. The data source doesn’t allow you to do that easily right now. That’s an area that I ran into a lot of conceptual problems. I had a hacky way to make it work, but I don’t like to do hacky things. I want it to work in the way the frameworks expects it to work. There’s some cool stuff coming up with the nested records which will hopefully help solve that problem.
FC: Where there any other mechanisms that you put into your Sudoku games that really helped put your application together?
MH: Yes, absolutely — Statecharts. It’s so much easier to manage the workflows in a statechart then it is with controllers because it really allows you to separate your concerns well. Having the statecharts be responders, picking up the events as they fire, and knowing which state comes next is incredibly powerful. It’s just a really useful abstraction. The other thing I was using was SCUDS, which is an open source module for SproutCore that allows you to do a lot of things, one of which is write data to the local storage.
FC: Regarding statecharts, can you give an example of what kind of states you had to create in order to organize workflow and event handling?
MH: Sure. A good example is the final verification in the game. If you click the verify button you go into the start verification state, but the user might not be sure that they are done. I want to give them a chance to go back and review the board and make modifications. The start verification state is responsible for popping up up a little dialog asking if the user is sure they are done, because if the user is not done then they can’t go back and make changes. By clicking “no” you can go back to reviewing and modify the board. By clicking “yes” then you continue on with the actual verification. This means I go to one of two states. If “no” is clicked then the user goes back to the play state where they can continue to play. If “yes” is clicked then they go to a do verification state that checks to see if the board is correct, and then they move onto the verification complete state. It’s really just small, modular bits of code. Even the complicated states were only ten lines of code. From a development point of view, you always want to separate your concerns, so having all this workflow logic coded up in the states allows everything else to be simple — that’s where the value is. Ki is a really excellent implementation of statecharts, and it even allows you to test your states independently. The power is there but you don’t have to use everything Ki provides for it to be beneficial.
FC: Given that you’ve now published your game, where would like to apply improvements to the game itself?
MH: I have been thinking of where to go next. I’ll probably work on integrating the Google’s OAuth APIs so the game can be installed in other browsers, and on the iPad.
Another possibility is keeping track of statistics. Basic stuff like how many games I have played at each level; how many have I solved correctly; what’s the average time I’ve spent on a game; when there are errors, how many cells on average do I have wrong; how many streaks am I on; and separate those out into each level. I would store that into local storage. Eventually I would have to put a server behind this, so if the user clears their browser data they don’t lose their hard earned stats.
Honestly, there’s no limit to how far I can take this game. For example, I could add social integration, such as posting to Twitter after beating a really difficult level. It’s a matter of having the time. My wife tells me I have to get off this computer thing [laughs].
FC: [Laughs] That’s fair. Outside of the game itself, now that you’ve been using SproutCore pretty heavily, where would like to see improvements to the framework?
MH: So it’s easy to define records in SproutCore, and I understand the abstraction and usefulness that record attributes provide, but the nested records functionality I mentioned earlier would be really useful. People are going to want that, and I see it being mentioned on the SproutCore google group and whatnot. The bottom line is, not every record type is going to have its own server endpoint, so the framework should support that.
Another thing I’d like to see is an excellent, first-class table view. SproutCore does have one, but it’s still not at the point I’d like to see it at. I want it to be really simple, functionally complete, and robust. It’s another thing I see come up in various discussions on Sproutcore.
FC: In addition to improvements you’d like to see, what where the parts of SproutCore that you found challenging at first?
MH: The only real issue with Sproutcore is that there is a learning curve before you can really be productive. Each functional area has its complexities and is challenging to understand in its own way.
One of toughest things to understand is how the KVO and bindings work because there can be a lot of complexity there. KVO and bindings aren’t the same thing. A value connected with a binding only updates during a run of the SproutCore run-loop; KVO happens immediately. With observers happening immediately that can lead you into issues if you’re not sure what you’re doing.
As an example, I got caught up with KVO and binding issue when building Sudoku. The user entered a value into a cell and the cell had an observer to tell the board to recalculate all of its hints, but what was happening was the cell’s value was bound to a higher level object and the observer was at the level of the cell. The observers were firing but the bindings had not yet propagated the actual value. So you can potentially run into issues where data has changed and observers fire, but then when you do something with the data before its been updated because the run loop had to complete. Now, once you understand this, it’s not a hard fix. For someone who is dead new to this stuff, there can be a lot of confusion.
FC: Right. When I first started with SproutCore, KVO and bindings did put me in a bit of a loop, but once I understood them the power they provided me was phenomenal.
MH: Absolutely. It’s great. I wrote very little code when entering a value into a cell and getting it to recompute all the hints for the cell, and the reason I was able to do that was because of the KVO and bindings. That’s the value.
FC: If you were to go back and do your Sudoku application all over again, would you do anything differently?
MH: [Laughs] I probably would’ve written more tests. That would allow me to make changes with confidence, and I always preach test driven development, but sometimes it can be difficult to stick to principles. Every time I don’t write tests I inevitably get to a point where I wish I had those tests. Also, I have a lot of code in Git that isn’t in the deployed version yet. If I could go back, I would try to be a bit more focused than I was. With respect to my framework choice, I’m a firm believer in Sproutcore, so I wouldn’t chose another framework. I was developing a real rich-internet application [RIA], and Sproutcore is a framework for RIA development, so it was a really good match.
Something else that is cool is when you’re developing an application for the desktop, you handle mouse down and mouse up events, but in order to get my game to run on the iPad, all I had to do was write a separate set of event handlers for touch start and touch end. I took the code that was for the mouse down and mouse up event handlers and put it into general methods that could also be called by the touch event handlers. Everything just worked, and it was pretty snappy when running the game on the iPad. SproutCore is heading in the right direction. I’m pretty happy with the results.
FC: As a quick final thought, where do you see the future of desktop-like applications for the Internet going?
MH: Well, as newer technology becomes available, such as HTML5, browsers get faster, and mobile devices get more prevalent, where going to see true rich Internet applications. The browser is going to become a platform for running applications that people won’t even know they’re running in a browser other than the fact that they opened Firefox or Chrome. The capability is getting there. It’s definitely exciting.
FC: Mike, thank you for taking time out of your busy day to do this interview.