I don’t usually recommend iPhone games here, but I stumbled upon Hook Champ a week ago and i’ve been ‘hooked’ since. It’s a speedy platform, jumping/swinging game with a classic 8-bit retro style. Its highly addictive and great fun in vs. mode, trying to outpace your competitor to the finish. Playing takes me on a nostalgic trip back to the excellent Rick Dangerous series on the Amiga.
I’ve also been reading the dev blog for The Incident another retro styled iPhone game due for release soon. It’s interesting to see how the developer (Matt Comi) approaches different aspects of the game on the iPhone SDK.
ActsAsTextcaptcha - pretending to be human just got tougher!
You can also play around with a working demo on heroku.
The gem can be configured with your very own logic questions (to fall back on if the textcaptcha service is down) or as a replacement for the service. It also makes use of bcrypt encryption when storing the answers in your session (recommended if you’re using the default Rails CookieStore)
The gem contains two parts, a module for your ActiveRecord models, and a tiny helper method (spamify).
A call to spamify(@model) in your controller will query the Text CAPTCHA web service. A restful GET request is made with Net::HTTP and parsed using the standard XML::Parser. A spam_question is assigned to the model, and an array of possible answers are encrypted in the session.
validate_spam_answer() is called on @model.validate() and checks that the @model.spam_answer matches one of those possible answers in the session. This validation is only carried out on new records, i.e. never on edit, only on create. User’s attempted spam answers are not case-sensitive and have trailing/leading white-space removed.
BCrypt encryption is used to securely store the possible answers in your session. You must specify a valid bcrypt-salt and (computational) cost in your options. Without these options possible answers will be MD5-hashed only.
allowed?() and perform_spam_check?() are utility methods (that can be overridden in your model) They basically act as flags allowing you to control creation of new records, or whether the spam check should be carried out at all.
If an error occurs in loading or parsing the web service XML, ActsAsTextcaptcha will fall back to choose a random logic question defined in your options. Additionally, if you’d prefer not to use the service at all, you can omit the api_key from your options entirely.
If the web service fails or no-api key is specified AND no alternate questions are configured, the @model will not require spam checking and will pass as valid.
For more details on the code please check the documentation.
Text CAPTCHA’s logic questions are aimed at a child’s age of 7, so they can be easily solved by all but the most cognitively impaired users. As they involve human logic, such questions cannot be solved by a robot. There are both advantages and disadvantages for using logic questions rather than image based captchas, find out more at Text CAPTCHA.Rob Tuley of Openknot
Finally, since things have changed so much over the years, i’ll be doing a refresher post on the state of play for creating/testing and releasing a Rails gem/plugin from scratch.
If you choose to install as a plugin, or are interested in the code, the following rake tasks are available;
Here’s a few links on Rails 3 I’ve collected in preparation for its release. I haven’t read these all through yet, or started using Rails 3 in any way, but I have a couple of production apps primed and waiting to be upgraded as soon as it launches.
Start with this one from RubyInside, 36 links to get you going
And finally some official release notes;
Be opinionated. In software its important. I’d go as far as saying it can completely make or break your app. It’s something that 37signals have been advocating for a long time, and something they practice daily in saying ‘No’. In fact in both Rework and Getting Real it is clearly stated that saying ‘No’ should be the default answer when considering any new feature (including their own!) I couldn’t agree more.
What happens when you don’t say no? It leads directly to feature bloat or in the long-term a big ball of mud. And if your business is beholden to clients who can throw financial weight around, then your’e really in trouble. You can end up second guessing their needs or prospecting new features that will attract them. This can be more true in b2b products where I think it can be much harder for people to say ‘No’ by default.
Apple take sides in a very obvious way. Rather than be all things to all people, they continually make game changing decisions that their competitors probably haven’t even considered. No DVD-drive in the Apple Air, loosing the conventional right-mouse button, more often than not they are constantly removing and simplifying their products. Look at everything thats not built into the iPad, you’ll find a long list of features if you compare against traditional touchpad devices.
All this creates division (and a buzz) amongst fans and critics. But have you ever heard an outcry over the latest updates to Microsoft Office? People just don’t care when an already bloated app tries to be all things to all people (and yes, I’m writing this post in Writeroom)
In building Bugle I have made lots of decisions along the way in code, the interface and even the server stack. Drawing on my own experiences and motivations has helped to keep things simple. Im not doing competitor comparisons or even looking at what people consider normal steps in the processes. I’m just defining the problems a user faces and trying to offer the simplest solution that will meet their needs.
Of course opinions matter in blog posts too, so what do you think, agree or disagree?
So, i am officially entered in this years Berlin Marathon a full three years since I hobbled across the line in New York. Given my current going, I really need to up the milage soon while still keeping a good pace. I’ve set myself the small goal of completing it in (or under) 3.5hrs!
I’ve stuck to Phoenix Park and the surrounding area, but as soon as the weather picks up I’ll have to give the Wicklow mountains a go again. I’ll get some sponsorship links up here (and on twitter) soon.
(the USMC cadences are great for keeping a regular pace, I found a few of these mp3’s on the internets)
Just a quick update to explain what I’ve been working on lately.
Some years ago (lets say 3) I was approached by a long-time business pal. He had the idea of creating a very simple FAQ gathering web application. It would offer no other features, only questions and answers, and would provide a rich knowledge base for those working in the field of project management. Sound familiar ?
As the years passed and other projects, distractions got in the way, the FAQtory (as it was named) was put on hold. Then in September 2008, stackoverflow launched and soon after their 3rd party offering, stackexchange and following that an entire barnyard of clones; stacked, cnprog, soclone to name a few.
This was all a bit dis-heartening, given we had the idea some years ago and never jumped on it. Around Christmas last year, I picked up the FAQtory again, dusted it off and got to work in my spare time building it. Right now I am at the final stages of styling the UI and launching the first version as a sub site at pmfaqtory.com.
some notebook sketches made while designing the FAQtory
So with my attention on the FAQtory, work on Bugle has been put on hold. After the FAQtory launches however, i’ll be back developing on it again. Being a one-man show its hard to maintain a focus on more than one app at a time. Im encouraged by Rework and DHH’s concept of a little italian restaurant on the web
I’ve learnt a great deal from building these two apps and in many cases I’ve applied learning gained from experiences in one, to the other. I also have some valuable by-products I hope to share. I’ve already mentioned some on this blog and on github. So stay tuned, in future posts I’ll try to explain more of the decisions I’ve made while building each app, and hopefully get around to open sourcing more code.
,----------------------------------------------------, |    [__]  | | | | [_]   | | [_][ |   | | [_]||   | | [__][__]  || | | [__][________________][__] [__]|| | `----------------------------------------------------'