20 May 2013

Century cycle ride training

Last year I completed my first century cycle ride (a rather windy Century Cycle Challenge from Nevill Holt in Leicestershire to Brancaster on the north Norfolk coast). This year I'm going to try the 3 Counties 100 Cyclosportive which is a circular route through Northamptonshire, Leicestershire and Rutland.

I followed a simple nine week training plan  last year with targets for the longest ride and longest distance each week building up the event.

This year I've created a Century Training Plan web app so I can easily track my training against the plan. It integrates with the Google MyTracks app that I use on my phone to record my training rides and show me how I'm doing.

Head over to the web app and set the event date to use the plan for your own ride. Here's a plan for the 3 Counties 100 Cyclosportive.

To integrate it with your own training ride data you can either use MyTracks or record your ride details in a Google Drive spreadsheet. See the instructions on the page for details.

6 February 2013

Simple aggressive caching with Google App Engine

For the HTML5 version of my puzzle game Persuasion, I wanted to make sure the static resources (images, stylesheets, javascript etc) get cached for as long as possible but still ensure that I can push out new versions whenever they change.

One way of doing this is to embed a version number in the URL for each resource file. You can then give the resources an expiry time far in the future and, when you need to update them, change the version number and reference them at the new URL.

This is pretty straightforward with Google App Engine since you automatically get a versioned URL for your application at versionstring.yourapplication.appspot.com. So you can keep your app at yourapplication.appspot.com (or a custom domain) and reference your resources at the versioned URL. As a bonus this also means you avoid the overhead of cookie data being sent with every resource request.

For example, in my case I just use base and relative URLs to reference the resources:



  <!-- "3-owap" is the name of the current version of my app -->
  <base href='//3-owap.persuasiongame.appspot.com/persuasion/' />

  <!-- Use relative URL to reference resource file -->
  <script src="res/js/main.js" type="text/javascript"></script>


Then set a long expiration for your resources, e.g. (for a Java app):

  <include path="/persuasion/res/**" expiration="365d" />

15 April 2011

Amazon Appstore restrictive terms

This IGDA post very much echoes the concerns I had when I considering publishing to the Amazon Appstore.

Make sure you read it (and the full Amazon terms) before participating in the Amazon Appstore.

27 October 2010

Persuasion Android app

I recently published my first Android app. It's a puzzle game called Persuasion. You can search for it on the market or find out more at persuasion.codesimple.net.

Here's a few things I learnt in the process:

  • Developing for Android is pretty pleasant: the documentation and tools are good and comprehensive. And if, like me, you're not a fan of Eclipse you don't have to use it: The tools will generate an Ant build file for your project complete with an install task to run the app on your device or emulator. I imported this into a Java Free-Form Project in NetBeans to get code-completion goodness whilst still using the standard build file.
  • If you want to add global highscores to your game, I'd recommend Scoreloop. Basic integration is easy and I found the support excellent.
  • Don't be afraid of the dips. I initially wrote my app to run in "compatibility mode" (i.e. the Android System will pretend the screen is 320x480 regardless of the device). For a game, I thought it would be hassle switching to using dips and handling this stuff myself. It wasn't. All I needed to do was work in dips internally, grab the density from DisplayMetrics and then use it to scale to pixels when calling drawing APIs and scale from pixels when receiving input events.
  • If you're planning to do multiple versions of the app (e.g. a free and a paid one) use a Library Project. You can then put all your shared code and resources in a separate project. Create a new project for each variant and the build script will take care of merging the resources and code.

22 September 2009

That Big Shop

I've always found shopping at Amazon a bit of a cumbersome experience. The pages seem a little cluttered and when choosing between products there's lots of back-and-forth as you switch between search results and product detail.

So I thought I'd make use of the Amazon Product Advertising API and write my own interface. The result is That Big Shop. It's not old browser or search engine friendly but it does, I think, have a more responsive feel to it than the standard Amazon interface.

To create the site, I choose to use the Cappuccino framework and I'm glad I did. The painful part of writing web applications is getting them to look and work the same across browsers. With Cappuccino I didn't need to worry about that; as long as I coded to the framework API, Cappuccino would take care of rendering what I wanted consistently across browsers.

12 August 2008

QR codes for cogteeth.com

With a little help from the Google Chart API, I've added the ability to create QR code t-shirt, mugs and cards over at cogteeth.com.

QR codes are quite nifty little two-dimensional barcodes which can store a surpising amount of data in a small space. There are numerous readers available to decode them including mobile phone apps which enable you to decode them using your phone camera.

Any data can be stored in these codes but there are a number of standards or conventions recognised by the readers. For example, many will detect an encoded URL and automatically pull up the referenced web page. The documentation for the zxing reader gives a good summary of these conventions.

15 April 2008

Google App Engine

It took less than two hours to convert cogteeth.com to run with the Google App Engine. Admittedly this is a pretty simple example since cogteeth doesn't use a database and Django is supplied with the App Engine environment.

All that was necessary was:

  1. Create a main.py: Since the app is Django based this was just a modified copy of the version on this page.
  2. Create an app.yaml to pass all URLs onto main.py and serve the static files directly.
  3. Modify some URL fetching code that previously used urllib2 to use urlfetch.
When I say it's running with the App Engine that's not strictly true. It runs locally with the SDK, now I just have to hope they work through the wait list quickly and send me an invite...