Hello World!
I'm a Developer at Master of Malt, a University of Brighton graduate, a 1st Kyu in Kyokushinkai Karate, a video gamer and technology enthusiast. Read more about me over here.
CloudANDTidus
Search
Gaming With Lemons
Games


Monday
May232011

Here come the test results: You are a horrible person. That’s what it says. Horrible person. We weren’t even testing for that.

Poster Day for the project seemed to go well, especially when you bribe your examiners with whisky samples. A few guys from a local company also attended the session and seemed fairly impressed with my work. They offered me the chance to attend an interview day they were holding, which could have led to a job, however I decided not to submit my CV because apparently they build all their websites in perl…

Quite why you would do that, I'm not exactly sure. They said it gets them "deep down" into the hardware, increasing performance, but I don't really believe them. It appears to me that their first developer knew perl and everyone else was forced to continue using it. The same argument could be made for writing everything in machine code, which I have little desire to do either.

In my last post I showed an early version of the flash game we had to build as a group. The game is now finished, however because its a two player game requiring a server, I can't put it online like I did my first one. Instead I have produced this overly dramatic video demonstrating it.

We worked as a team to create the game. My major contributions to the project were the tank controls, timers and turn switching, the start and end sequences and conceptual designs. Other team members produced the assets (graphics and sound, which are far superior to my previous effort), collision detection, random rock layout and the server side work. We had planned to have other weapon types, but ran out of time. I'm really happy with how it came out though, and its surprisingly fun to play.

With that handed in I have officially completed all the coursework for my degree. All that is left is a couple hand written exams next month. Exciting stuff!

In the meantime I've been getting back into the swing of completing video games. I completed Portal 2 twice (with and without commentary) just after my project. The game is without question a must play, and if you didn't play the original you should play both of them immediately. The writing and humour is some of the best video games has to offer, and the puzzles are perfectly play tested. Valve added so many new unique twists to the original concept that I often sound myself banging my head against a puzzle I couldn't solve, and then remembering that I had a portal gun…

I also went back and completed Assassin's Creed: Brotherhood. Back at the start of the year I played and completed the first two games back to back after getting a PS3 at Christmas, however I stopped playing Brotherhood only a few hours into it after getting some fatigue. While improved, Brotherhood is very much a second act of AC2, so its perhaps not wise to play them consecutively. I did really enjoy the entire game though (I don't think the mechanics of scaling rooftops and assassinating will ever get old), and the ending is as unpredictable as the first two. If your new to the series as I was, and want to catch up, I recommend reading the wikipedia article and watching some YouTube videos for the first game, before skipping it and playing the sequel. While you need to know the story to play AC2, the gameplay in AC1 is incredibly repetitive and frustrating and one of those rare occasions where the sequel is 100% better.

With Brotherhood out the way I'm now enjoying L.A. Noire, Rockstar's mix of Grand Theft Auto and Phoenix Wright. So far I'm enjoying it immensely.

Tuesday
May102011

Do you know who I am? I'm the man who's gonna burn your house down! With the lemons!

What's up world?

As I showed in the previous post, I completed the documentation for my project, an epic tome of a report. The last month has been a fairly stressful period in which I spent consecutive days in the same room typing away, while being constantly concerned that all the work simply wasn't going to get done. It was certainly close, but I can now happily say it is done. For those interested in reading more about my project than was represented on this blog, you can check out the two main portions of my report in delightful PDF form.

The Exaiminers Report - This is a short report designed to give a complete overview of the project, aimed at the non-technical reader.

The Product Report - This is a more in-depth report designed to explain, in unnecessary detail, how each individual component of the app works.

This Friday is Poster Day, where we get to show of the final product and get questioned about the project. That will draw a close to my final year project as a whole.

In this glorious post-project world we now live in, I'm moving focus to the last waining weeks of the semester. Last week I had to (quickly) complete two more essays for deadlines, and next week I have a presentation and a multiplayer flash game to hand in. The flash game is a team project and has been quite enjoyable after all this essay writing. Our game is going to be a turn based tank game where you play as either Maria Sharapova on the Soviets team or Sarah Palin on the Republican team.

This screenshot shows the development of the game itself. Ignore the rather unsightly grid, that is there for development purposes only. Currently each client can control their own tank (move forward, backward, rotate the tank and rotate the turret), and the movements of your tank is reflected on your opponents screen. The rocks littering the play field are also randomly positioned when the game begins.

Between all this I've also begun working on a little personal side project in the last couple weeks to get away from all this work. It's a website that allows you to build a list of the games you own and track your progression in them, how long you've played them, if you completed it, etc. It's using Giant Bomb's API so that I don't have to build my own game's database and is coming along nicely. I don't intend to really promote or pimp the final product, its really much more for my own OCD, but I will add sign up functionality should anyone else like to use it. If nothing else, its a fun way to get back into PHP and learn some jQuery. I asked Sputin on MSN for a name that I could get the domain for, and after batting ideas back and forth I eventually settled on "My e-penis.com". If you don't get the joke, its the fact gamer's have refereed to achievements and gamer score as your "e-penis". Its hilarious I know...

Speaking of video games, I really want to blog about them some more now that I'm starting to have some time. I finished Portal 2 (twice!) in breaks from writing my project documentation and this weekend I returned to Assassin's Creed: Brotherhood after a long break. Man is that game fun.

Of course, exams are just over three weeks away, so I'm not off the hook yet.

Wednesday
Apr272011

I can kill you with my brain.

My project is done.

I'm going to crawl into a dark corner and die now.

Friday
Apr222011

We gotta go to the crappy town where I'm a hero.

Today marks the beginning of the last week of work on my final year project. I've been spending a lot of time recently writing in elaborate detail about very boring things. Documenting everything isn't terribly fun…

I've done nearly 30 pages for my product report. Tomorrow I will add testing and planning to it and it should be mostly done. Then I need to create a short user manual. And then I need to write the 5000 - 7000 word report to the examiners in which I have to explain my project to people who don't know what the Internet is…

While "working on project without really doing any work" I managed to produce the following video. I thought it might help anyone who bothers to look at the disc submitted with my project as its very unlikely they will actually be able to run my code. It will probably also be useful for my portfolio and poster day…



In other news, Portal 2 arrived today. Its awesome.

Friday
Apr012011

You've been seeing parts of the life of a barber in Indiana for seven years, and you never mentioned it?

Alo world! 

So I've been silent on here for about a month now. The last month or so has been pretty hard on me emotionally, with the loss of Tabby the cat on Februrary 24th and Hamish, my family dog, on 14th March. 

Tabby was very old for a cat at 19, and she had been increasingly "loosing it", so her eventual death was to be expected, whether I wanted to accept it or not. I think the thing that truly effected me most with Tabby was the fact she had always been there. Being 22 I don't really recall a time when Tabby wasn't around, and as she got older she eventually confined herself to my bedroom, which made us much closer.  

Hamish was a lot less expected. I knew he was old, sure, but up until about a week before his death he seemed perfectly fine and happy. Unfortunately it seems his breed isn't particularly well designed, because they tend to suffer from incredibly itchy skin that causes them to bite and rip at their hair until it bleeds. To stop this he's been on medication for a very long time. He also had arthritis, ear infections and once nearly went blind in one eye from an infection. Eventually it was the medication that simply became to much for his system and his kidneys began to fail. He stopped eating, and the time came when we had to make the decision. Loosing him upset everyone in the family greatly, including my mum who made herself physically ill for over a week and managed to get an eye infection brought on by stress that could have made her blind. 

 

Add having to deal with work and university onto this and well… I wouldn't say I have been exactly on my game recently. 

As for my final year project, I didn't get every feature I wanted in the app, however with the deadline just a month away, I had to draw a line and start on the laborious documentation process. Its obviously not feature complete and ready for the app store, but that was never the goal of my project. What I've produced allows you to browse a massive collection of whiskies, whether or not your online, add them to one of four lists (wish list, basket, collection or empties) and then proceed into a checkout when you want to buy something.

What the app doesn't currently do is send the order to the server for processing (not within the scope of my app), allow you to add tasting notes, image caching on the local device for when you are offline, or sync the product data after the initial download. The last three are all things I will discuss in my documentation and are things the final product will do, but I simply didn't have the time when developing my project.

So what have I done to the app since I last talked about it? One of the most obvious changes was improving the product list views. Before you couldn't even read the full product name. Now the full name is readable on two lines, and a small third line provides extra information such as ABV, volume, age and price. At some point it would be neat to get images into list views (they would have to be place holders that change into images as they are downloaded to not affect performance), but I don't have this yet.

On the product "page" I replaced the no image image that was displayed before the product image downloaded with a loading indicator as everyone I showed this to was confused with why the no image image switched to a real image. The loading indicator makes much more sense here, telling the user that the image is loading. 

I also added a couple features to the social card on the product page. This is where you will eventually be able to add tasting notes. For now you have a more clear button that adds the product to a list (for people who miss the + button in the top right), as well as a share with friends and email friends option. The share with friends button gives you the ability to share the product on either Facebook or Twitter. This is done by launching the selected website in mobile Safari with the product's URL pre-populated. One day this might be better implemented by using the services API's to keep you inside the app. The other option, email friends, launches an email form with URL pre-populated.

One other small change, the add to list screen now gives a clear indication to the user when a product is out of stock by making the basket button red, however they still have the option to add it to their basket if they wish.

With the small changes covered, we move on to the lists screen, which is where the majority of my time has been consumed. To be honest, this feature took much longer than I had originally anticipated. The list screen was originally four separate instances of the same view accessible in the tab bar along the bottom of the screen, however the client suggested it would be better to consolidate these into one screen to give them the ability to have other options in the tab bar later. I achieved this using a segment control. When you select one of the lists in the segment control, the table view bellow is refreshed with different data.

You can click on an item in a list, which spins the screen to reveal the ability to adjust quantity. I imagine in the future that this screen would also be where you would add accessories or a gift message to a product. When you try to save the quantity the app does a call to the server if the current list is the basket. If the server responds with the product is currently out of stock, the quantity of the product is set to zero and the user is told to remove it from their basket. If the user requests more bottles than we currently have they are alerted of the current stock level and asked to select a different quantity. If there is no internet connection the app will accept whatever quantity the user asks for, and will instead alert the user of any issues with their basket when they try to go to checkout.  

The list view allows you to delete a product by swiping and clicking the delete button, or by clicking edit, the red circle, and then the delete button. By clicking edit they can also re-order the list using the little icon to the right of every item. To achieve this I had to add a rank field to the database that indicates the order of the items in the list. Every time a product is delete or moved, the ranking order has to be re-assigned for the entire list. Add a product simply requires adding one to the current total of list items.

Clicking the checkout button takes you to the checkout. If you are offline you are stopped immediately, as the checkout requires a connection to the server. If your basket has issues (such as an out of stock product or a larger quantity than we can provide), an error message is displayed and the user is required to go and correct it. If everything is successful the server responds with a set of delivery options.

I had a meeting with my client to spec how the delivery options would work. Their currently delivery algorithm is over complicated and in need of a re-write, so I was asked to write a simple algorithm for the iPhone app (which only needs to concern itself with UK orders) until the new one is built.

The business rules for the delivery algorithm I built are:

If all the stock required is available at the local warehouse offer:

  1. next day (two day if after 3pm) for £6.95
  2. three day for £5.95
  3. five day for £4.95 (£3.95 if the order has one bottle)

If some of the stock is only available from the supplier in Scotland offer:

1. Ship each item as it is ready for £13.90 (two deliveries of £6.95)

  • the local stock will be delivered next day or two day if after 3pm
  • the supplier stock will be delivered in four days

2. One Delivery (saves money)

  1. four day for £6.95
  2. six day for £5.95
  3. eight day for £4.95

If all the stock is only available from the supplier in Scotland offer: 

  1. four day for £6.95
  2. six day for £5.95
  3. eight day for £4.95

I used the UIPicker control to offer these options in the checkout. This particular control caused a lot of problems, mostly due to my inexperience with how it worked. 

If you try to submit the order without providing your details, you will be rejected. The user has the ability to add a delivery address, billing address and payment method to the order. The app keeps a list of every address and payment method added, allowing the user to simply select an existing one if it has already been entered (e.g. from a previous order or if the billing address is the same as the delivery). The screens where these details are entered are probably the least polished part of the app as it stands today, with little validation or enhancements, such as a UIPicker for selecting title and card expiry dates. You also have to click into the address/payment method to have it "selected" for the order. A better way to do with would be having clicking the item in the list select it (with some sort of indicator that it is selected, like a check mark), and the user having to enter an edit mode to have clicking the item take you to the edit screen.

Finally when the completed order is submitted, a confirmation is provided, although as I mentioned before, the order is not sent to the server. For poster day I would like to have a very basic implementation of sending the order to a temp table on the server's database and displaying that on a grid view so I can demo the phone sending the order and the site receiving it just to prove it works (although no processing or charging will have taken place obviously), however I have yet to do this. 

So thats an update. From here on its documentation time.

Sunday
Feb272011

An excellent plan, with just two drawbacks: One, we don't have a power source for lasers; and Two, we don't have any lasers.

It's been a few weeks since I gave a good project update. Except for some cosmetic changes and the addition of a few new categories on the home screen, the majority of the work I've done is on the product "page" itself. Navigating through lists of products and making it easy to find what your looking for with categories and search is important, but the ultimate goal of the app is the product itself.

I decided to go with a long panoramic scroll view that moves left and right to give the user a break from the long up and down scrolling experienced in the navigation. I choose the "card" metaphor that the user swipes between to help them understand what is going on, as I found giving the app to people when the background was solid white introduced confusion as they didn't understand what was going on. The cards made it perfectly clear to them.

The cards (from left to right) show the product full name and image, facts such as price, availability, distillery and style, a bottling note describing the product, a tasting note (if we have one) and user reviews (if we have any). Depending if we have a tasting note or user reviews, the product "page" will have between three and five cards. Pressing the plus button in the top right brings up a menu which allows you to add the product to one of your three lists (wish list, basket and collection). The user reviews are downloaded from a call to a web service when the view loads to reduce the size of the initial product download. The xml is processed the an extra card "pops" onto the end of the list when the reviews are ready.

The image doesn't initially appear when the view loads as it has to be downloaded over the web. If your on a slow connection this could take some time so I plan to add a loading indicator, as well as caching to the local disk so that the image doesn't have to be called every time. Initially I had used synchronous downloading of the image, but this locked up the interface as the download was happening. This issue was solved by implementing asynchronous downloading, which works by using NSURLConnection to start the download. Delegate methods are then called independently of the main loop which receive the image data as it comes in, then loads the image into an ImageView once the download is complete.

For the tasting note and bottling note I had to use a UIWebView rather than a UIScrollView because the text from the database contains HTML formatting for the website. The UIWebView is normally used to open a website in your app, however you can also give it a NSString of HTML. I hid the fact I was using a web view by disabling the bouncing when you pull a web view down and adding a background that matched the app.

Today I just finished using the plus button to add a product to your wish list, basket or collection. I had quite a bit of trouble working out how to  query relationships in Core Data as I have to add a product to a list for a user. The solution was to get the requested list from the List table, get all the CustomerList's for the selected List and Customer, then pull the Drinks out of the relationship link between the CustomerList (link table) and the Drink table.

Oh, and of course I forgot to mention my Apple developer account finally got approved (there was some delay due to having to fax documentation to Apple). This not only allows me to use the gold master version of XCode 4 before release (which is a huge improvement over the last version of the IDE), but also deploy my app to my device. This is particularly useful because performance between the simulator and the real device can be surprisingly different.

Monday
Feb072011

Don't answer to twinkle toes, its not manly!

Halló world!

I've done a lot of work on my project over the last few days in the navigation department, best described by these pictures!

At the bottom of the screen I've added the tab bar control that will allow the user to switch between browsing products and their three lists (wish list, shopping basket and collection). Currently the three lists are multiple instances of the same view that is currently empty as a place holder. In the browse section you have the ability to either browse all products, or browse by a category such as country, style, distillery or price range. Clicking on any of the categories takes you to a view where you can select an option within that category. Clicking one of those (or all products on the top level) takes you to the product list view, where the products for that section are populated.

I've broken up the product listings by letters of the alphabet, which you can jump between using the bar of letters down the right hand side of the screen (which really helps with long lists). On the product list view you also have the option to use the search box at the top to filter the current list of products by a search query.

Both this site, and this one were very useful in showing me how to break up the product list by letter and add the letter index on the right. I didn't end up following their exact implementations as they weren't quite fit for my purpose. Instead I used a single NSMutableDictionary which contained an array list of products for each letter of the alphabet. I then used an NSMutableArray to store all the letters the current product list actually had (there are only 24 letters in the all products list for example), so that I know what to display in the index and which letters to query the dictionary when building the list.

The first site also had a tutorial on how to build a search box, but after some more research I found out that in 3.0 of the SDK Apple added a UISearchDisplayController which basicly does all the work for you. They have some great documentation for this object over here.

All you have to do is create and add a search bar to your table view and then attach the search bar to the search display controller. From here everything is mostly handled for you and you can use some delegate methods to update the datasource of the table view for the query searched.

- (void)viewDidLoad {
    if (!self.tableView.tableHeaderView) {
        
        // Add the search bar
        UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
        self.tableView.tableHeaderView = searchBar;
        
        UISearchDisplayController *searchController = [[UISearchDisplayController alloc]
                                                       initWithSearchBar:searchBar
                                                       contentsController:self];
        searchController.delegate = self;
        searchController.searchResultsDataSource = self;
        searchController.searchResultsDelegate = self;
    }
}

In non-project news, the week before last I started learning how to build a proper WordPress theme. I've dabbled in WordPress before, most using other peoples themes or hacking a pre-made theme to my need, however it seems a lot simpler just to start from scratch. I've been the webmaster of the Final Fantasy VII Citadel for a little while now, but I've really neglected it due to other commitments. One of my biggest desires has been to move its static html pages into a content management system and generally modernise the look of the site, without loosing its look and feel. I took a look at a lot of pre-made WordPress templates, but finally accepted I wasn't going to find anything quite right.

I'm using some of the images of how the site used to look like back in 2001, 2004 and now as some of my inspiration to try and keep some of the look and feel. This is how it currently looks, although obviously there is still a lot to do. Feedback is most welcome!

Inspired by working on a new version of the Citadel, I fired up Final Fantasy VII on my PS3 and ended up getting 40 hours into it (I'm at the start of disc 3). It's been a long time since I had a working copy of the game (my disc one is fucked, so thank you PSN), and man did I forget how much I liked the game. I'm thinking of marathoning through VIII, IX and X once I finish this one, just for the hell of it...

Today was the first day of the second (and last!) semester of my University degree, so it really should be all work from here, but you gotta relax sometime right? Last week I (finally) completed a project I've been doing at work for the last few months (I built a stock ordering system for them, its not at all exciting), so I plan to do a lot less for them in the next couple months (except for my project of course) as we lead up to deadlines and exams.

Oh, I almost forgot; after two weeks I finally got my MacBook back from Apple (if you don't remember, the backlight was turning off at random). If you Google the issue it seems to be a common problem with an "inverter board" (an £18 part) which the Genius said was probably the issue when I took it in. When I picked it up they had replaced the inverter board (which hadn't fixed the problem), logic board and lcd, plus they gave me a new palm rest, keyboard and track pad (the second one in a year) because it was showing signs of getting the crack of doom again. In all a £18 repair became £650 including VAT. Thank God I got the student Apple Care for just £40. Including the palm rest repair last year, Apple has spent over £750 repairing a machine I only paid £800 for. I'm surprised they still like me...

Tuesday
Feb012011

Don't give me any of that 'Star Trek' crap. It's too early in the morning.

Haanjee world!

It's been a little while since I gave an update. Sorry about that. It's currently the second of two exam weeks (in which I have no exams), so I've been spending my time either working (at work), working on university stuff, working on a website I've neglected in some time and (God forbid) socialising with the outside world.

Project-wise, stuff is comming along steadily. I had quite a bit of trouble over the last few days getting core data to play nicely with the information I was downloading from the webservice. The app would recieve the data, store it all nicely in the managed object context (the object you use to interact with the data in the db as objects, which is commited back to the database when the app is suspended or killed) and even display the information it stored to screen, but as soon as the app was closed and reopen, it had forgot the data and had to redownload it.

These two lines of code (not permited in a submitted app as they use a private class, but very usefull for debugging) were useful in showing me the route of the problem.

Class privateClass = NSClassFromString(@"NSSQLCore");
[privateClass setDebugDefault:YES];

These two lines make all the raw SQL statements core data runs in the background display in the console, and after adding them it was quite clear that my app wasn't running the 2000+ comit lines for the products it had downloaded. I feared briefly that it wasn't going to allow me to commit such a large number of items. I ended up solving the problem by creating a new project and implementing a very basic version of the app with harded projects added when it launched. This worked perfectly, which lead me to realise I wasn't adding products to the context in the right way when I downloaded them. A bit of refactoring and my problem was solved.

At the same time I extracted all the work involved with downloading products from the webservice into a dedicated class called ProductFeed. I then used iOS's notification center to register my view controller as a observer of this class so that it would be informed when ProductFeed had finished downloading and parsing the XML. This allows the download to happen asynchronously in the background. I also made a very simple "Drink" class so that I could move product data around as a single object.

This image shows the current state of the app. You get the main category menu (currently hard coded) when the app launches (which triggers a product download if the database is empty) and when you select a category, you are taken to a second view where all the products are listed. Currently all the options lead to the same product list, so my next job will be to introduce a sub category view when all but "all products" is selected so that you can, for example, select a particular region you wish to see whisky from.

This second image shows the output from the console. You can see the first time I launched the app the database was empty (as it will be the first time it is used), so a connection is made to the webservice and the products are downloaded. The second time the app is launched is has products in the database, so it simply uses those, allowing the app to work offline after its first use.

Finaly this image gives you an idea of what my database looks like. It has a drink table for storeing product data, a customer table for customer information, a list table to contain the different lists a user will be able to make (wish list, collection, basket) and a link table that records a product in a list for a customer.

That's about it for project progress. I think things are progressing well right now, however I do need to dedicate more of my time to coding if I'm going to finish in time.

Page 1 ... 2 3 4 5 6 ... 8 Next 8 Entries »