Skip to content

Portfolio

Things I’ve built

Projects and tools I’ve taken from an idea to a live site.

Projects

  • Nemesis Rewards Calculator

    2026

    Finds the cheapest way to back Nemesis Legacy on Gamefound for exactly what you want.

    The calculator with Nemesis Legacy, Retaliation and Lockdown switched on, showing a best order of €442.00 including shipping to the United States.
    Three games chosen, in the default Nemesis style.
    The list of what to add to the Gamefound cart: the Legacy, Retaliation and Lockdown pledges, each with its box art, price and shipping.
    The cart list, in the red Lockdown style.

    The campaign sells four games through dozens of pledges, bundles and add-ons that overlap, so the cheapest way to get a given set of items is rarely obvious, and shipping, VAT and currency all move the final bill. Backers switch on what they want; the calculator returns the cheapest combination, the full price and the exact cart lines to add.

    How it’s built

    Nuxt 4 and Vue 3
    Every page is generated to static HTML at build time and hydrated in the browser. There is no server: all the working-out happens client-side.
    TypeScript, at its strictest
    The catalogue, classification, shipping, tax, solver and quote are plain typed modules kept apart from the UI, with every optional compiler check on and CI failing on a single lint warning.
    An exact set-cover solver
    Choosing what to buy is a weighted set-cover problem. A recursive search decides one bundle at a time and splits what is left into independent sub-problems per game, so it finds the true optimum in about a millisecond and reruns on every click.
    Bun
    Package manager, script runner and test runner. The tests check the solver against a brute-force search over random selections, and fail if Gamefound adds a product the classifier does not know.
    A capture-and-build data pipeline
    Gamefound turns scripts away, so a browser-console script captures the catalogue; a Bun script then builds the shipped catalogue and fetches the product images, optimised with sharp.
    Nuxt UI and Tailwind CSS
    Components and four switchable themes, one per game, restored before first paint so there is no flash of the wrong colours.
    Frankfurter API
    Central-bank exchange rates for 27 currencies, fetched by the browser, falling back to the rates captured with the catalogue.
    GitHub Actions and Pages
    CI runs lint, formatting, type checks, tests and a full build on every pull request; pushes to main deploy to its own domain. Pages cannot send headers, so each page carries a Content Security Policy with a hash for every inline script.
  • This CV

    2026

    My CV as a fast, accessible website, with PDF and Word downloads built from the same source.

    A CV has two audiences: people who skim it, and applicant tracking systems that parse it. Keeping a web page, a designed PDF and an ATS-friendly version in step by hand means they drift apart. Here one set of data builds all of them, so a change lands everywhere on the next deploy.

    How it’s built

    Vue 3 and Vite
    Single-file components render the page. Content lives in data and Markdown files, one per role with frontmatter, never in the templates.
    Vue SSR prerendering
    Vite builds a client and a server bundle; a build script renders each page to HTML and injects it, so the CV reads fully without JavaScript, then hydrates for the theme toggle and menus.
    Tailwind CSS 4
    Colours are CSS custom properties: a dark palette, and a high-contrast light one derived from it. An inline script applies the saved or system theme before first paint.
    jsPDF and docx
    At build time a shared view model feeds text-based PDF and Word files in two versions: a branded one for people, and a plain single-column one shaped for applicant tracking systems.
    sharp
    Generates AVIF, WebP and JPEG versions of the portrait at build time.
    GitHub Actions and Pages
    Each push to main checks formatting and lint, builds and deploys. A weekly job checks every link and opens an issue if any break.
  • the BIG GAME

    2001–2014

    The website for the BIG GAME, a long-running LAN party near Southampton, which I built and looked after from 2001 to 2014.

    A volunteer-run LAN party lives or dies on its signups. The site had to sell a weekend of gaming to new players, take signups and payments against a fixed number of seats, keep regulars in the loop between events and give the community somewhere to talk, all run by a handful of crew in their spare time.

    The BIG GAME (tBG) started in 2000 and runs a few times a year from Friday evening to Sunday, latterly at Wildern School in Hedge End. Up to 80 or so gamers bring their own PCs for tournaments, a Saturday pizza run (the record is 69 pizzas), a pub quiz and the BIG GAMER title, whose Golden Joystick trophy earns free entry to the next event.

    How it changed

    1. The 2001 homepage: red links on black, a menu down the left, a case-mod sponsor banner and news posts about the BIG GAME 5.
      2001Black and red, hosted by PlanetLAN: a text menu, news posts, a photo gallery for each event and sponsor banners. Entry was £20 booked or £25 on the door. See it on the Wayback Machine (2001, opens in a new tab)
    2. The late-2002 homepage: a purple circular BIG game logo beside a banner of game characters on black, above forum topics and news posts.
      2002 to 2003The first full redesign: the purple BIG game roundel and a banner of game characters, with the latest forum topics, comments on news, an IRC quote of the day and online signups. See it on the Wayback Machine (2002 to 2003, opens in a new tab)
    3. The 2005 homepage: a three-column lilac layout with THE BIGGAME, A South UK LAN Party in the header, menus either side and news in the middle.
      Late 2003 to 2009The longest-lived version, running on my own tag-based template engine: a three-column portal in lilac and purple with news, articles, a gallery for every event, signup and payment pages, live signup counts, sponsor slots, forum threads and hardware reviews. See it on the Wayback Machine (Late 2003 to 2009, opens in a new tab)
    4. The December 2013 homepage: 16 seats remaining of 80, a sidebar with the event date and venue, and a poster for tBG35.
      Late 2009 to 2014Rebuilt as plain PHP pages with the news written in the forum: a cleaner centred layout with a new logo, a seat counter showing paid, unpaid and remaining places, event posters, tournament signups, Steam and Facebook links, and the Golden Joystick front and centre. See it on the Wayback Machine (Late 2009 to 2014, opens in a new tab)

    How it’s built

    A home-made template engine
    From 2003, pages lived in MySQL and pointed at templates full of custom tags such as <$news$> and <$signupcounter$>. Each tag was a small PHP plug-in loaded on demand, with attributes, modifiers, nested tags for repeating items, and a cache so a tag used twice ran once.
    PHP and MySQL
    PHP 4, then 5, over MySQL for news, articles, signups, payments and sponsors. The 2010 rewrite swapped the engine for plain PHP pages behind a single front script.
    vBulletin integration
    The vBulletin 3 forums shared the database: the homepage listed the latest threads, and from 2010 the news itself was written as forum posts and pulled onto the site, with the forum’s RSS feed for subscribers.
    Signups, payments and tickets
    Signups with an anti-bot question (the number of the event), a live seat count, payment by NoChex and later PayPal, bank transfer or cheque, and a crew list of paid and unpaid. Each attendee’s ticket key was derived with CRC32 and printed as a barcode for check-in.
    Hire PCs, sponsors and galleries
    Loan PCs from PlanB Gaming booked through the site with live availability and interest counts, sponsor banners that counted clicks before redirecting, and a gallery for every event, later on Gallery 2.
    HTML, CSS and JavaScript
    Table-based HTML 4 layouts built from sliced graphics, JavaScript for drop-down menus and a countdown to the next event, and a PNG fix for Internet Explorer 6.
    Nub, a library on Zend Framework
    For the crew’s intranet: my own extensions to Zend Framework 1 for access control, sign-in, database tables, jQuery UI forms, Bootstrap view helpers and Steam profile look-ups, alongside LightOpenID and the PayPal and Google SDKs.
    Community channels
    IRC on QuakeNet with a quote of the day on the homepage, and later a Steam group and Facebook events for each BIG GAME.