More than you expected?

You're reading everything on Dan's blog - including notes, reposts, checkins, videos and comics.
That might be more than you wanted to see, if you're only interested in blog posts (articles) Dan has written.

I Will Never Stop Learning

I’ve been doing a course provided through work to try to improve my ability to connect with an audience over video.

This is my fourth week in the course, and I opted to revisit a video I made during my second week and try to do it again with more engagement, more focus, more punch, and more emotion. I’m pretty pleased with how it turned out. Interestingly, it somewhat mirrors my Howdymattic video from when I first started at Automattic, but I pivoted my “origin story” a little bit and twisted it to fit one of my favourite parts of the Automattic Creed.

Shot during the same outing as the Devil’s Quoits one. Also available on YouTube.

The Devil’s Quoits

I’ve been doing a course provided through work to try to improve my ability to connect with an audience over video. For one of my assignments in this, my fourth week, I picked a topic out from the “welcome” survey I filled out when I first started the course. The topic: the Devil’s Quoits. This stone circle – not far from my new house – has such a bizarre history of construction, demolition, and reconstruction… as well as a fun folk myth about its creation… that I’d thought it’d make a great follow-up to my previous “local history” piece, Oxford’s Long-Lost Zoo. I’d already hidden a “virtual” geocache at the henge, as I previously did for the zoo: a video seemed like the next logical step.

My brief required that the video be only about a minute long, which presented its own challenge in cutting down the story I’d like to tell to a bare minimum. Then on top of that, it took me at least eight takes until I was confident that I’d have one I was happy with, and there’s still things I’d do differently if I did it again (including a better windbreak on my lapel mic, and timing my takes for when geese weren’t honking their way past overhead!).

In any case: part of the ritual of this particular course encourages you to “make videos… as if people will see them”, and I’ve been taking that seriously! Firstly, I’ve been sharing many of my videos with others either at work or on my blog, like the one about how GPS works or the one about the secret of magic. Secondly, I’ve been doing “extra credit” by recording many of my daily-standup messages as videos, in addition to providing them through our usual Slack bot.

Anyway, the short of it is: you’re among the folks who get to see this one. Also available on YouTube.

Hey ONS: This Is Not A Mistake

Hi, ONS! I know we haven’t really spoken since you ghosted me in 2011, but I just wanted to clear something up for you –

This is not a mistake (except for the missing last names):

(Specimen) 2021 census form on which Ruth declares that she cohabits with both a husband AND a partner.
It’s perfectly possible for somebody to live with multiple partners, even if they’re forbidden from marrying more than one.

Back in 2011 you thought it was a mistake, and this prevented my partner, her husband and I from filling out the digital version of the census. I’m sure it’s not common for somebody to have multiple cohabiting romantic relationships (though it’s possibly more common than some other things you track…), but surely an “Are you sure?” would be better than a “No you don’t!”

Clippy says "It looks like you've got a husband AND a partner. Is that right?" with possible answers "Yes, and it's awesome." or "No, but I can dream!"
For all I know, you already fixed it. If not: I mocked-up a UI for you.

We worked around it in 2011 by using the paper forms. Apparently this way you still end up “correcting” our relationship status for us (gee, thanks!) but at least – I gather – the originals are retained. So maybe in a more-enlightened time, future statisticians might be able ask about the demographics of domestic nonmonogamy and have at least some data to work with from the early 21st century.

I know you’re keen for as many people as possible to do the census digitally this year. But unless you’ve fixed your forms then my family and I – and thousands of others like us – will either have to use the paper copies you’re trying to phase out… or else knowingly lie on the digital versions. Which would you prefer?

Tribute to Peter Huntley

This article is a repost promoting content originally published elsewhere. See more things Dan's reposted.

While I was traipsing off around the countryside to commemorate the anniversary of the death of my dad, one of his former colleagues uploaded to YouTube a video that he originally produced for the UK Bus Awards Presentation Ceremony 2012.

As his son, it felt a little weird for me to be marking the occasion on what: the ninth anniversary of his death? It’s not even a nice round number. But clearly I’m not the only one whose mind drifted to my father on 19 February.

Fun fact: this photo – extracted from the video – was originally taken by me:

Peter Huntley, circa 1985, in a bus depot.
My dad’s crouching to make sure he’s in the frame, because I was less than half his height at this point. The horizon is wonky because I’m crouching too, in order to imitate him, and I’ve lost my balance. Altogether, I rate this piece of photographic art… umm: not bad for a preschooler?

Maybe I should be asking for royalties! Or at least, using the video as an excuse to springboard my career as a professional photographer.

YouTube ID badge showing that Chris Cheek has only one subscriber.
What kind of exposure could I get? Oh.

Well, maybe not then.

The Varieties of Intimate Relationship

This article is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Diagram dividing varieties of intimiate relationships into monogamy, polyamory, celebacy, and a few things in-between.

A slightly tongue-in-cheek (see the “serial monogamy” chain and some of the subtitles!) but moderately-complete diagram of popular varieties of relationship structure. Obviously there’s gaps – relationships are as diverse as their participants – and lots of room for refinement, but the joy of an infographic is making visible the breadth of a field, not in providing encyclopaedic comprehension of that field. I especially like the attention to detail in “connecting” often-related concepts.

Retrohashing expedition 2012 02 19 51 -1

This checkin to geohash 2012-02-19 51 -1 reflects a geohashing expedition. See more of Dan's hash logs.


Field behind Hill Barn, near the Gom’s Hole public footpath, in the valley beneath the hamlet of Clapton-on-the-Hill. About 4km outside the village of Bourton-on-the-Water, Gloucestershire.

(Retro) Participants

  • Dan Q (as a retrohash on the same date but 19 years later, on 2021-02-19)

(Retro) Plans

On the second anniversary of the death of my father, a man who loved to get out into the world and get lost, I undertook my first geohashing expedition. As this seemed to be a good way to remember him I decided to repeat the experience on this, the ninth anniversary of his death, but the actual hashpoints for the day didn’t look interesting… so I opted to make my way to what would have been my nearest hashpoint on the day he died.

(Retro) Expedition

The weather looked horrible and the COVID lockdown (and working from home in general in recent years) has put me out of practice at cycling, so I thought a 40-50 mile round trip through the rolling hills of the Cotswolds was just the thing. This may have been a mistake, as my aching legs were able to testify for several days.

Cycling through Witney, over the hills behind Burford, and then across the Windrush valley and into Gloucestershire was a long, arduous, and damp journey, but what really got me was the wind picking up in the afternoon and giving me a headwind to fight against all the way back home.

Near the hashpoint I was able to lock my bike up at the junction between Sherbourne Street and Bourton Hill – a place shown on my map as “Gom’s Hole” which sounds exactly like what a D&D dungeon master would have a goblin would name his bar. From there I followed the footpath towards Farringdon. As the hashpoint drew closer I began to suspect that it would be unreachable: tall walls, fences, and hedges stood on both sides of the (flooded) footpath, but at the last minute they gave way to wide meadows. I turned off the path and crossed a dyke to the hashpoint, where I had a great view of hares and deer in the valley below. Minutes later, the owner of Hill Barn came over with her dog and asked what I was doing around the back of her land and why I was taking pictures, so I explained that I’d strayed from the footpath (true) because my GPS had told me too (technically true) but I was heading back down to what I could see was the path, now (true, if misleading).

She continued to watch me all the way back to my bike, so I changed my plans (which had been to eat a sandwich lunch and drink a pint of Guinness: my dad’s beer of choice) near the hashpoint and instead I cycled away to a nearby layby to have my lunch.

After a 48.3 mile round trip I got back home aching and exhausted, but pleased to have made it to this damp hashpoint.

(Retro) Tracklog

GPX tracklog: Track 2021-02-19 RETROHASH 2012.gpx

(Retro) Photos

Map of 51.8569418,-1.7795905

Basilisk collection

This article is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Basilisk collection

The basilisk collection (also known as the basilisk file or basilisk.txt) is a collection of over 125 million partial hash inversions of the SHA-256 cryptographic hash function. Assuming state-of-the art methods were used to compute the inversions, the entries in the collection collectively represent a proof-of-work far exceeding the computational capacity of the human race.[1][2] The collection was released in parts through BitTorrent beginning in June 2018, although it was not widely reported or discussed until early 2019.[3] On August 4th, 2019 the complete collection of 125,552,089 known hash inversions was compiled and published by CryTor, the cybersecurity lab of the University of Toronto.[4]

The existence of the basilisk collection has had wide reaching consequences in the field of cryptography, and has been blamed for catalyzing the January 2019 Bitcoin crash.[2][5][6]

Electronic Frontier Foundation cryptographer Brian Landlaw has said that “whoever made the basilisk is 30 years ahead of the NSA, and the NSA are 30 years ahead of us, so who is there left to trust?”[35]

This is fucking amazing, on a par with e.g. First on the Moon.

Presented in the style of an alternate-reality Wikipedia article, this piece of what the author calls “unfiction” describes the narratively believable-but-spooky (if theoretically unlikely from a technical standpoint) 2018 disclosure of evidence for a new presumed mathematical weakness in the SHA-2 hash function set. (And if that doesn’t sound like a good premise for a story to you, I don’t know what’s wrong with you! 😂)

Cryptographic weaknesses that make feasible attacks on hashing algorithms are a demonstrably real thing. But even with the benefit of the known vulnerabilities in SHA-2 (meet-in-the-middle attacks that involve up-to-halving the search space by solving from “both ends”, plus deterministic weaknesses that make it easier to find two inputs that produce the same hash so long as you choose the inputs carefully) the “article” correctly states that to produce a long list of hash inversions of the kinds described, that follow a predictable sequence, might be expected to require more computer processing power than humans have ever applied to any problem, ever.

As a piece of alternate history science fiction, this piece not only provides a technically-accurate explanation of its premises… it also does a good job of speculating what the impact on the world would have been of such an event. But my single favourite part of the piece is that it includes what superficially look like genuine examples of what a hypothetical basilisk.txt would contain. To do this, the author wrote a brute force hash finder and ran it for over a year. That’s some serious dedication. For those that were fooled by this seemingly-convincing evidence of the realism of the piece, here’s the actual results of the hash alongside the claimed ones (let this be a reminder to you that it’s not sufficient to skim-read your hash comparisons, people!):


claimed: 00000000000161b9f84a187cc21b1752bf678bdd4d643c17b3b786684d8e9f17
 actual: 0000000000000000000000161b9f84a187cc21b172bf68b3cb3b78684d8e9f17


claimed: 0000000000000000000000cee5fe5df2d3034fff435bb40e8651a18d69e81460
 actual: 0000000000cee5fe5df2d3034fff435bb4232f21c2efce0e8651a18d69e81460


claimed: 000000000000000000000012aabd8d935757db173d5b3e7ae0f25ea4eb775402
 actual: 000000000012aabd8d935757db173d5b3ec6d38330926f7ae0f25ea4eb775402


claimed: 000000000000000000000039d50bb560770d051a3f5a2fe340c99f81e18129d1
 actual: 000000000039d50bb560770d051a3f5a2ffa2281ac3287e340c99f81e18129d1


claimed: 00000000000000000000002ca8fc4b6396dd5b5bcf5fa80ea49967da55a8668b
 actual: 00000000002ca8fc4b6396dd5b5bcf5fa82a867d17ebc40ea49967da55a8668b

Anyway: the whole thing is amazing and you should go read it.

Review for ProtonMail Encryption Status by Morgan Larosa

This article is a repost promoting content originally published elsewhere. See more things Dan's reposted.

Does what it says on the tin! Short and sweet codebase that’s easy enough to verify personally, and doesn’t ask for any crazy permissions.

I probably needn’t care about this validation: when I wrote a Thunderbird plugin to enhance integration with ProtonMail, I wrote it principally for myself: scratching my own itch. It was nice to see that (at time of writing) a few hundred other people have made use of the extension too, but it wasn’t essential. I’d be maintaining it regardless because I use it every day.

But it still warmed my heart to see a five-star review come in alongside a clearly-expressed justification.

The Coolest Thing About GPS

I’m currently doing a course, through work, delivered by BetterOn Video. The aim of the course is to improve my video presentation skills, in particular my engagement with the camera and the audience.

I made this video based on the week 2 prompt “make a video 60-90 seconds long about something you’re an expert on”. The idea came from a talk I used to give at the University of Oxford.

The Secret of Magic

I’m currently doing a course, through work, delivered by BetterOn Video. The aim of the course is to improve my video presentation skills, in particular my engagement with the camera and the audience.

I made this video based on the week 2 prompt “make a video 60-90 seconds long about something you’re passionate about”. The idea came from a blog post I wrote back in 2014.

Coca-Cola company trials first paper bottle

This article is a repost promoting content originally published elsewhere. See more things Dan's reposted.

image captionThis image from Coca-Cola's filling line gives a clear view of the plastic cap still in use

Coca-Cola is to test a paper bottle as part of a longer-term bid to eliminate plastic from its packaging entirely.

The prototype is made by a Danish company from an extra-strong paper shell that still contains a thin plastic liner.

But the goal is to create a 100% recyclable, plastic-free bottle capable of preventing gas escaping from carbonated drinks.

The barrier must also ensure no fibres flake off into the liquid.

If only somebody could invent a bottle suitable for containing Coca-Cola but 100% recyclable, plastic-free, and food safe.

Oh wait… for the vast majority of its history, all Coca-Cola bottles have met this description! The original Coke bottles, back in 1899, were made of glass with a metal top. Glass is infinitely-recyclable (it’s also suitable for pressure-washing and reusing, saving even more energy, as those who receive doorstep milk deliveries already know) and we already have a recycling infrastructure for it in place. Even where new glass needs to be made from scratch, its raw ingredient is silica, one of the most abundant natural resources on the planet!

Bottle caps can be made of steel or aluminium and can be made in screw-off varieties in case you don’t have a bottle opener handy. Both steel and aluminium are highly-recyclable, and again with infrastructure already widespread. Many modern “metal” caps contain a plastic liner to ensure a good airtight fit (especially if it’s a screw cap, which are otherwise less-tight), but there are environmentally-friendly alternatives: bioplastics or cork, for example.

The worst things about glass are its fragility – which is a small price to pay – and its weight (making distribution more expensive and potentially more-polluting). But that latter can easily be overcome by distributing bottling: a network of bottling plants around the country (each bottling a variety of products, and probably locally-connected to reclamation and recycling schemes) would allow fluids to be transported in bulk – potentially even in concentrate form, further improving transport efficiency… and that’s if it isn’t just more ecologically-sound to produce Coke more-locally rather than transporting it over vast distances: it’s not like the recipe is particularly complicated.

In short: this is the stupidest environmental initiative I’ve seen yet this year.

Entles (Gender-Neutral Aunts, Uncles, etc.)

Enfys published an article this week to their personal blog: How to use gender-inclusive language. It spun out from a post that they co-authored on an internal Automattic blog, and while the while thing is pretty awesome as a primer for anybody you need to show it to, it introduced a new word to my lexicon for which I’m really grateful.

The Need for a New Word

I’ve long bemoaned the lack of a gender-neutral term encompassing “aunts and uncles” (and, indeed, anybody else in the same category: your parents’ siblings and their spouses). Words like sibling have been well-established for a century or more; nibling has gained a lot of ground over the last few decades and appears in many dictionaries… but we don’t have a good opposite to nibling!

Why do we need such a word?

  • As a convenient collective noun: “I have 5 aunts and uncles” is clumsier than it needs to be.
  • Where gender is irrelevant: “Do you have and aunts and/or uncles” is clumsier still.
  • Where gender is unknown: “My grandfather has two children: my father and Jo.” “Oh; so you have an Aunt or Uncle Jo?” Ick.
  • Where gender is nonbinary: “My Uncle Chris’s spouse uses ‘they/them’ pronouns. They’re my… oh fuck I don’t even remotely have a word for this.”

New Words I Don’t Like

I’m not the first to notice this gap in the English language, and others have tried to fill it.

I’ve heard pibling used, but I don’t like it. I can see what its proponents are trying to do: combine “parent” and “sibling” (although that in itself feels ambiguous: is this about my parents’ siblings or my siblings’ parents, which aren’t necessarily the same thing). Moreover, the -ling suffix feels like a diminutive, even if that’s not its etymological root in this particular case, and it feels backwards to use a diminutive to describe somebody typically in an older generation than yourself.

I’ve heard that some folks use nuncle, and I hate that word even more. Nuncle already has a meaning, albeit an archaic one: it means “uncle”. Read your Shakespeare! Don’t get me wrong: I’m all for resurrecting useful archaic words: I’m on a personal campaign to increase use eyeyesterday and, especially, overmorrow (German has übermorgen, Afrikaans has oormôre, Romanian has poimâine: I want a word for “the day after tomorrow” too)! If you bring back a word only to try to define it as almost-the-opposite of what you want it to mean, you’re in for trouble.

Auntle is another candidate – a simple fusion of “aunt” and “uncle”… but it still feels a bit connected to the gendered terms it comes from, plus if you look around enough you find it being used for everything from an affectionate mutation of “aunt” to a term to refer to your uncle’s husband. We can do better.

A New Word I Do!

But Enfys’ post gave me a new word, and I love it:

Here are some gender-neutral options for gendered words we hear a lot. They’re especially handy if you’re not sure of the gender of the person you’re addressing:

Mx.: An honorific, alternative to Mr./Mrs./Ms.
Sibling: instead of brother/sister
Spouse: instead of husband/wife
Partner, datefriend, sweetheart, significant other: instead of boyfriend/girlfriend
Parent: instead of mother/father
Nibling: instead of niece/nephew
Pibling, Entle, Nuncle: instead of aunt/uncle

Entle! Possibly invented here, this is the best gender-neutral term for “the sibling of your parents, or the spouse of the sibling of your parents, or another family member who fulfils a similar role” that I’ve ever seen. It brings “ent” from “parent” which, while etymologically the wrong part of the word for referring to blood relatives (that comes from a PIE root pere- meaning “to produce or bring forth”), feels similar to the contemporary slang root rent (clipped form of “parent”). It feels new and fresh enough to not be “auntle”, but it’s similar enough to the words “aunt” and “uncle” that it’s easy to pick up and start using without that “what’s that new word I need to use here?” moment.

I’m totally going to start using entle. I’m not sure I’ll find a use for it today or even tomorrow. But overmorrow? You never know.

Axe Feather 2021


I recreated a 16-year old interactive ad. Experience it here. Get the source code here. Or keep reading for the full story.


Back in 2005 I reblogged a Flash-based interactive advert I’d discovered via del.icio,us. And if that sentence wasn’t early-naughties enough for you, buckle up…

A woman lies on a bed with her legs crossed, playfully wagging her finger.
This screenshot isn’t from the original site but from my homage to it. More on that later.

At the end of 2004, Unilever brand Axe (Lynx here in the UK) continued their strategy of marketing their deodorant as magically transforming young men into hyper-attractive sex gods. This is, of course, an endless battle, pitting increasingly sexually-charged advertisements against the fundamental experience of their product, which smells distinctly like locker rooms and school discos. To launch 2005’s new fragrance Feather, they teamed up with London-based design agency Dare Digital to create a game at domain (long since occupied by domain squatters).

In the game, the player’s mouse pointer becomes a feather which they can use to tickle an attractive young woman lying on a bed. The woman’s movements – which vary based on where she’s tickled – have been captured in digital video. This was aggressively compressed using the then-new H.263-ish Sorensen Spark codec to make a download just-about small enough to be tolerable for people still on dial-up Internet access (which was still almost as popular as broadband). The ad became a viral hit. I can’t tell you whether it paid for itself in sales, but it must have paid for itself in brand awareness: on Valentines Day 2005 it felt like it was all the Internet wanted to talk about.

Axe Feather logo visible via, circa August 2005, in a Firefox browser window.
The site was archived by the WayBack Machine… but it doesn’t work in a modern browser.

I suspect its success also did wonders for the career of its creative consultant Olivier Rabenschlag, who left Dare a few years later, hopped around Silicon Valley for a bit, then landed himself a job as Head of Creative (now Chief Creative Officer) with Google. Kudos.


I told you about the site 16 years ago: why am I telling you again? Because this site, which made headlines at the time, is gone.

And not just a little bit gone, like a television ad no longer broadcast but which might still exist on YouTube somewhere (and here it is – you’re welcome for the earworm). The website went down in 2009, and because it was implemented in Flash the content was locked away in a compiled, proprietary format, which has ceased to be meaningfully usable on the modern web.

IE-specific CSS with a comment "Ok, so the scrollbar is IE specific...but I like it, ok?? :)"
The parts of’s code that are openly readable don’t help much, but I love this comment, which carries the scent of the adolescent web in the same way at Lynx deodorant carries the scent of an adolescent human.

The ad was pioneering. Flash had only recently gained video support (this would be used the following year for the first version of YouTube), and it had so far been used mostly for non-interactive linear video. This ad was groundbreaking… but now it’s disappeared like so much other Flash work. And for all that Flash might have been bad for the web, it’s an important part of our digital history [recommended reading].

Ruffle window showing an empty bed.
Third-party Flash emulation is imperfect. I tried to make Axe Feather work in Ruffle and got… an empty bed? What is this, a metaphor for being a lonely nerd?

So on a whim… I decided to see if I could recreate the ad.

Call it lockdown fever if you like, because it’s certainly not the work of a sane mind to attempt to resurrect a 16-year-old Internet advertisement. But that’s what I did.


My plan: to reverse-engineer the digital assets (video, audio, cursor etc.) out of the original Flash file, and use them to construct a moderately-faithful recreation of the ad, suitable for use on the modern web. My version must:

  • Work in any modern browser, without Flash of course.
  • Work on mobile devices/with touchscreens, with all of the original functionality available without a keyboard (the original had secret content hidden behind keyboard keypresses). Nowadays, Rabenschlag knows to put mobile-first, but I think we can forgive him for not doing that twelve months before Flash Lite 2.0 would bring .flv support to mobile devices…
  • Indicate how much of the video content you’d seen, because we live in an era of completionists who want to know they’ve seen it all.
  • Depend on no third-party frameworks/libraries: just vanilla HTML, CSS, and JavaScript.

Let’s get started.


Handbrake converting 19.flv to MP4 format.
At this point I noticed that the videos had no audio tracks: the giggling and other sound effects must be stored separately.

I grabbed the compiled .swf file from and ran it through SWFExtract and an online decompiler: neither was individually able to extract all of the assets, but together they gave me a full set. I ran the .flv files through Handbrake to get myself a set of .mp4 files instead.

Two starting frames from the videos, annotated to show that they are not aligned to the same point.
In what appears to have been an exercise in size optimisation, the original authors cropped the videos differently depending on how much space was needed (e.g. if the subject stretched her arms above her head, more space would be required). Clearly, some re-alignment would be needed.

Seeing that the extracted video files were clearly designed to be carefully-positioned on a static background, and not all in the exact same position, I decided to make my job easier by combining them all together, and including the background layer (the picture of the bed) as a single video. Integrating the background with the subject meant that I was able to use video editing software to tweak the position, which I imagined would be much easier than doing so in code. Combining all of the video clips into a single file provides compression benefits as well as making it easier to encourage a browser to precache the entire video to begin with.

Four layer design. From bottom to top: web page, video (showing woman on bed), (transparent) canvas, cursor (shaped like a feather).
My design called for three “layers” above my web page: the video, a transparent (and usually hidden) canvas showing the hit areas for debugging purposes, and the feather-shaped cursor.

The longest clip was a little over 6 seconds long, so I split my timeline into blocks of 7 seconds, padding each clip with a freeze-frame of its final image to make each exactly 7 seconds long. This meant that calculating the position in the finished video to which I wanted to jump was as simply as multiplying the (0-indexed) clip number by 7 and seeking to that position. The additional “frozen” frames acted as a safety buffer in case my JavaScript code was delayed by a few milliseconds in jumping to the “next” block.

Davinci Resolve showing composition of the actress onto the bed in a timeline.
I used onion-skinning to help “line up” the actress with herself as I composited her onto the bed in a single unified video of 7-second blocks.

An additional challenge was that in the original binary, the audio files were stored separately from the video clips… and slightly longer than them! A little experimentation revealed that the ends of each clip lined up, presumably something to do with how Flash preloads and synchronises media streams. Luckily for me, the audio clips were numbered such that they mostly mapped to the order in which the videos appeared.

Once I had a video file suitable for use on the web (you can watch the entire clip here, if you really want to), it was time to write some code.

Video timeline showing that each 7-second block is comprised of the original clip plus padding, atop a background layer of the bed and each clip's associated audio.
It feels slightly wasteful that over 50% of the resulting video clip is a freeze-frame, but modern video compression algorithms like H.264 reduce the impact considerably and the resulting video file is about the same size as its more-optimised predecessor.

Regular old engineering

The theory was simple: web page, video, loop the first seven seconds until you click on it, then animate the cursor (a feather) and jump to another seven-second block before jumping back or, in some cases, on to a completely new seven second block. Simple!

Of course, any serious web development is always a little more complex than you first anticipate.

Game map illustrating transition between the states of Axe Feather 2021.
I extracted from the .swf 34 distinct animated clips, which I numbered 0 through 33. 6 and 30 appeared to be duplicates of others. 0 and 33 are each two “idling” states from which interaction can lead to other states. Note that my interpretation of the order and relationship of animation sequences differs from the original.

For example: nowadays, putting a video on a web page is as easy as a <video> tag. But, in an effort to prevent background web pages from annoying you with unexpected audio, modern browsers won’t let a video play sound unless user interaction is the reason that the video starts playing (or unmutes, if it was playing-but-muted to begin with). Broadly-speaking, that means that a definitive user action like a “click” event has to be in the call stack when your code makes the video play/unmute.

But changing the .currentTime of a video to force it into a loop: that’s fine! So I set the video to autoplay muted on page load, with a script to make it loop within its first seven-second block. The actress doesn’t make any sound in block 0 (position A) anyway; so I can unmute the video when the user interacts with a hotspot.

For best performance, I used window.requestAnimationFrame to synchronise my non-interactive events (video loops, virtual cursor repositioning). This posed a slight problem in that animationframes wouldn’t be triggered if the tab was moved to the background: the video would play through each seven-second block and into the next! Fortunately the visibilitychange event came to the rescue and I was able to pause the video when it wasn’t being actively watched.

I originally hoped to use the cursor: CSS directive to make the “feather” cursor, but there’d be no nice way to animate it. Comet Cursor may have been able to use animated GIFs as cursors back in 1997 (when it wasn’t busy selling all your personal information to advertisers, back when that kind of thing used to attract widespread controversy), but modern browsers don’t… presumably because it would be super annoying. They also don’t all respect cursor: none, so I used the old trick of using cursor: url(null.png), none (where null.png is an almost-entirely transparent 1×1 pixel image) to hide the original cursor, then position an image dynamically.  I usegetBoundingClientRect() to allow the video to resize dynamically in CSS and convert coordinates on it represented as percentages into actual pixel values and vice-versa: this allows it to react responsively to any screen size without breakpoints or excessive code.

Once I’d gone that far I was able to drop the GIF idea entirely and used a CSS animation for the “tickling” motion.

Woman on bed in idle position B, with hotspots highlighted on each arm, her hed, her chest, her stomach, her hips, the top of her legs, and the bottom of the leg that's extended straight below her.
The hotspot overlay was added as a debugging feature but I left it in the final version. Hold the space bar to highlight hit areas.

I added a transparent <canvas> element on top of the <video> on which the hit areas are dynamically drawn to help me test the “hotspots” and tweak their position. I briefly considered implementing a visual tool to help me draw the hotspots, but figured it wasn’t quite worth the time it would take.

As I implemented more and more of the game, I remembered one feature from the original that I’d missed: the “blowaway”. If you trigger block 31 – a result of tickling the woman’s nose – she’ll blow your cursor off the screen. It’s particularly fun because it subverts the player’s expectations of their user interface: once you’ve got past the surprise of your cursor being a feather, you quickly settle in to it moving like a regular cursor… but then control’s stolen from you and the cursor vanishes! (Well I thought it was cool… 16 years ago.)

A woman blows a feather away from her face.
Sometimes tickling her nose will make her blow your feather off the screen. That’ll show you.

So yeah: that was my project this weekend.

I can’t even begin to explain why anybody would do this. But I did it. If you haven’t already: go have a play. And if you’re interested in how it works, the source code’s free for you to explore.