I’m not a big fan of job titles. I’ve always had trouble defining what I do as a noun—I
much prefer verbs (“I make websites” sounds fine, but “website maker” sounds kind of weird).
Mind you, the real issue is not finding the right words to describe what I do, but rather figuring out just what the heck it is that I actually do in the first place…
I am a survivor of an abusive relationship, and parts of that experience affect the way that I engage in romantic relationships… but I have difficulty quantifying exactly how
much. Insert obvious (minor) trigger warning here, and scroll past the kitten if you want to read more.
Mew.
I’m fine, by the way. It took… a long, long time, like in the region of a decade, to be completely fine about it, and I appreciate that compared to many people, I got
lucky. Like many victims (and especially among men), my recovery was hampered by the fact that I found it difficult to see the relationship as having been abusive in the first place:
that first step took many years all by itself. I’m not kidding when I say I’m fine, by the way: no, I don’t need to talk about it (with many of my circles of friends made up of current
and former helpline volunteers of various types, I feel the need to make that doubly-clear: sometimes, one just can’t escape from people who care
about you so much that they’ll offer you a cup of tea even if they’ve only got saltwater to make it with, if you catch the drift of my needless in-joke).
But I wanted to share with you something that I’ve gradually realised about how I was changed as a result of that relationship. Something that still affects me today and, for all I
know, probably always will: a facet of my personality whose origins I eventually traced back to that dreadful relationship.
Earlier this year, I finally got around to reading the (brilliant) Stories of Your Life and Others by Ted Chiang. As somebody who loves to take apart his own brain to see how it
works, I loved the story of an automaton who more-literally does exactly that.
A major factor in my attraction to people, for the last decade and a half, has been whether or not they demonstrate being attracted to me. I’m sure that’s the case for
everybody, at least to some extent – there’s a necessary reciprocity for a relationship to work, of course – but in my case there’ve been times in my past when the entirety of my
attraction to somebody could be described in terms of their attraction to me… and that’s a level that definitely isn’t healthy! It stems from a lack of belief in my own worth as
relationship material, which had grown to such an extent that feeling as if I were even-remotely attractive in somebody else’s eyes has, regardless of whether or not I’d be interested
in them under other circumstances, made me feel as though I ought to “give them a shot”. Again: not healthy.
This, in turn, comes from a desperation of considering myself fundamentally unattractive, undateable, and generally unworthy of the attention of anybody else in any
relationship capacity… which is highly tied-up in the fact that I had a relationship in which my partner repeatedly and methodically taught me exactly that: that I was lucky to be in a
relationship with them or indeed with anybody, etc.
Given enough time, persuasion, and coercive tactics, this is the kind of shit that sinks in and, apparently, sticks.
If this picture makes you sad… then you shouldn’t have scrolled past the kitten, should you?
I don’t mind that I’m a product of my environment. But it bugs me a little that I’m still, to a small (and easily managable, nowadays) extent the product of somebody else’s deliberate
and manipulative efforts to control me, a decade and a half after the fact.
Now I’ll stress once again that I’m fine now: I’ve recovered by as much as I need (or at least expect) to. Some years ago, I finally got to the point that if you let me know that you’re
attracted to me then that isn’t by itself something that makes me completely infatuated with you. Nowadays, I’m capable of actually engaging my brain and thinking “Hmm: would I
be interested in this person if it weren’t for the fact that they’d just validated my worth in some way?” But I’m still aware of the sensation – that nagging feeling that I’m acting
according to a manipulative bit of programming – even though I’m pretty confident that it doesn’t influence how I behave any more.
It’s funny how our brains work. At the end of the relationship, I made a reasonably-rapid bounceback/recovery in terms of my general self-worth, but it took far, far longer to
get control over this one specific thing. I guess we all react to particular stresses in different ways. For me, somebody who’d spent his childhood and teen years with perhaps, if
anything, a little much self-worth, it might have been inevitable that I’d be unable to rebuild the part of that self-image that was most-effectively demolished by somebody
else: the bit that is dependent upon somebody else’s validation.
But who knows… as I said, I have difficulty quantifying how much that abusive relationship impacted me. Because it is, of course, true to say that every single thing I’ve
ever experienced will have affected me in some way or another – made me the person I subsequently became. How can I justify blaming a single relationship? I know that I wasn’t
“like this” back when I first started my dating life, but I can’t conclusively prove that it was the result of any one particular relationship: for all I can claim, perhaps it was
something else? Maybe this was always who I’d become? Or maybe, of course, this entire paragraph is simply the result of the fact that my brain still has difficulty with the
term “abusive relationship” and is more-than-happy to keep trying to reach for whatever alternative explanations it can find.
Once again though, I’ll stress that I’m okay now and I have been for many years. I just wanted to share with you an observation I’d made about my own psychology… and the long
tail that even the “tamest” of abusive relationships can leave.
As you may know, I’ve lately found an excuse to play with some new web technologies, and I’ve also taken the opportunity to try to gain a deeper
understanding of some less bleeding-edge technologies that I think have some interesting potential. And so it was that, while I was staffing the Three Rings stall at last week’s NCVO conference, I made use of the
time that the conference delegates were all off listening to a presentation to throw together a tech demo I call Steer!
A player uses their mobile phone to steer a car on a desktop computer, using nothing more than a web browser.
As you can see from the GIF above, Steer! is a driving game. The track and your car are displayed in a web browser on a large screen,
for example a desktop or laptop computer, television, or tablet, and your mobile phone is used to steer the car by tilting it to swerve around a gradually-narrowing weaving road. It’s
pretty fun, but what really makes it interesting to me is the combination of moderately-new technologies I’ve woven together to make it possible, specifically:
The Device Orientation API, which enables a web application to detect the angle at which
you’re holding your mobile phone
Websockets as a mechanism to send that data in near-real-time from the phone to the browser, via a web server: for the
fastest, laziest possible development, I used Firebase for this, but I’m aware that I could probably get better performance by running a
local server on the LAN shared by both devices
The desktop browser does all of the real work: it takes the orientation of the device and uses that, and the car’s current speed, to determine how it’s position changes over the time
that’s elapsed since the screen was last refreshed: we’re aiming for 60 frames a second, of course, but we don’t want the car to travel slower when the game is played on a
slower computer, so we use requestAnimationFrame to get the fastest rate possible and calculate the time between renderings to work out how much of a change has
occurred this ‘tick’. We leave the car’s sprite close to the bottom of the screen at all times but change how much it rotates from side to side, and we use it’s rotated to decide how
much of its motion is lateral versus the amount that’s “along the track”. The latter value determines how much track we move down the screen “behind” it.
The track is generated very simply by the addition of three sine waves of different offset and frequency – a form of very basic procedural generation. Despite the predictability of mathematical curves, this results in a moderately organic-feeling road
because the player only sees a fraction of the resulting curve at any given time: the illustration below shows how these three curves combine to make the resulting road. The difficulty
is ramped up the further the player has travelled by increasing the amplitude of the resulting wave (i.e. making the curves gradually more-agressive) and by making the road itself
gradually narrower. The same mathematics are used to determine whether the car is mostly on the tarmac or mostly on the grass and adjust its maximum speed accordingly.
In order to help provide a visual sense of the player’s speed, I added dashed lines down the road (dividing it into three lanes to begin with and two later on) which zip past the car
and provide a sense of acceleration, deceleration, overall speed, and the impact of turning ‘sideways’ (which of course reduces the forward momentum to nothing).
This isn’t meant to be a finished game: it’s an experimental prototype to help explore some technologies that I’d not had time to look seriously at before now. However, you’re welcome
to take a copy – it’s all open source – and adapt or expand it. Particular ways in which it’d be fun to improve it might include:
Allowing the player more control, e.g. over their accelerator and brakes
Adding hazards (trees, lamp posts, and others cars) which must be avoided
Adding bonuses like speed boosts
Making it challenging, e.g. giving time limits to get through checkpoints
Day and night cycles (with headlights!)
Multiplayer capability, like a real race?
Smarter handling of multiple simultaneous users: right now they’d share control of the car (which is the major reason I haven’t given you a live online version to play
with and you have to download it yourself!), but it’d be better if they could “queue” until it was their turn, or else each play in their own split-screen view or something
Improving the graphics with textures
Increasing the entropy of the curves used to generate the road, and perhaps adding pre-scripted scenery or points of interest on a mathematically-different procedural generation
algorithm
Switching to a local LAN websocket server, allowing better performance than the dog-leg via Firebase
Greater compatibility: I haven’t tried it on an iPhone, but I gather than iOS devices report their orientation differently from Android ones… and I’ve done nothing to try to make
Steer! handle more-unusual screen sizes and shapes
Anything else? (Don’t expect me to have time to enhance it, though: but if you do so, I’d love to hear about it!)
Original log extremely damp, dampness spreading to new log. Needs some attention. CO: if you’re happy for a visitor to remove the old log, worth making a note to that effect?
After an extended trip to the nearby park – one of our little one’s favourite places – she was able to be persuaded to join me for a little hike around the village. This old water pump
(which she loved to play with) and the nearby cache was our first stop. An easy find: the little one was pleased to swap a sliding puzzle (which we barely managed to fit into the
container) for a marble. SL. TFTC!
After a lovely walk up from the pump at GC6PDXP, my 3 y/o geocaching buddy and I found this lovely cache with no difficulty. Could easily justify a larger container here!
Beautiful day and a great location. TFTC.
After a delightful hike across from two other caches, my 3 y/o geocaching assistant and I were optimistic about another find, but it wasn’t to be. It’s probably how well it’s
camouflaged, but we hunted high and low sound the GZ for some time without success. The hint didn’t mean anything to us, so we hunted some more, but eventually had to give up. Maybe
another day!
Maybe it’s because I was at Render Conf at the end of last month or perhaps it’s because Three
Rings DevCamp – which always gets me inspired – was earlier this month, but I’ve been particularly excited lately to get the chance to play
with some of the more “cutting edge” (or at least, relatively-new) web technologies that are appearing on the horizon. It feels like the Web is having a bit of a renaissance of
development, spearheaded by the fact that it’s no longer Microsoft that are holding development back (but increasingly Apple) and, perhaps for the first time, the fact that the W3C are
churning out standards “ahead” of where the browser vendors are managing to implement technical features, rather than simply reflecting what’s already happening in the world.
Ben Foxall at Render Conf 2017 discusses the accompanying JSOxford Hackathon. Hey, who’s that near the top-right?
It seems to me that HTML5 may well be the final version of HTML. Rather than making grand new releases to the core technology, we’re now – at last! – in a position where it’s possible
to iteratively add new techniques in a resilient, progressive manner. We don’t need “HTML6” to deliver us any particular new feature, because the modern web is more-modular and
is capable of having additional features bolted on. We’re in a world where browser detection has been replaced
with feature detection, to the extent that you can even do non-hacky feature detection in pure CSS, now, and
this (thanks to the nature of the Web as a loosely-coupled, resilient platform) means that it’s genuinely possible to progressively-enhance
content and get on board with each hot new technology that comes along, if you want, while still delivering content to users on older browsers.
And that’s the dream! A web of progressive-enhancement stays true to Sir Tim’s dream of universal interoperability while still moving forward technologically. I’ve no doubt
that there’ll always be people who want to break the Web – even Google do it, sometimes – with single-page Javascript-only web apps, “app
shell” websites, mobile-only or desktop-only experiences and “apps” that really ought to have been websites (and perhaps PWAs) to begin with… but the fact that the tools to make a genuinely “progressively-enhanced” web, and those tools are
mainstream, is a big deal. If you don’t think we’re at that point yet, I invite you to watch Rachel Andrews‘ fantastic presentation,
“Start Using CSS Grid Layout Today”.
Three Rings’ developers hard at work at this year’s DevCamp.
Some of the things I’ve been playing with recently include:
Intersection Observers
Only really supported in Chrome, but there’s a great polyfill, the Intersection Observer API is one of those technologies that make you say “why didn’t we have that
already?” It’s very simple: all an Intersection Observer does is to provide event hooks for target objects entering or leaving the viewport, without resorting to polling or
hacky code on scroll event captures.
What’s it for? Well the single most-obvious use case is lazy-loading images, a-la Medium or Google
Image Search: delivering users a placeholder image or a low-resolution copy until they scroll far enough for the image to come into view (or almost into view) and then
downloading the full-resolution version and dynamically replacing it. My first foray into Intersection Observers was to take Medium’s approach and then improve it with a Service Worker in order to make it behave nicely even if the user’s Internet connection was unreliable, but
I’ve since applied it to my Reddit browser plugin MegaMegaMonitor: rather than hammering the browser with Javascript the plugin now waits
until relevant content enters the viewport before performing resource-intensive tasks.
Web Workers
I’d briefly played with Service Workers before and indeed we’re adding a Service Worker to the next
version of Three Rings, which, in conjunction with a manifest.json and the service’s
(ongoing) delivery over HTTPS (over H2, where available, since last year), technically makes it a Progressive Web App… and I’ve been
looking for opportunities to make use of Service Workers elsewhere in my work, too… but my first dive in to Web Workers was in introducing one to the next upcoming version of MegaMegaMonitor.
MegaMegaMonitor’s processor-intensive “Lists” feature sees the most benefit from Web Workers
Web Workers add true multithreading to Javascript, and in the case of MegaMegaMonitor this means the possibility of pushing the more-intensive work that the plugin has to do out of the
main thread and into the background, allowing the user to enjoy an uninterrupted browsing experience while the heavy-lifting goes on in the background. Because I don’t control the
domain on which this Web Worker runs (it’s reddit.com, of course!), I’ve also had the opportunity to play with Blobs,
which provided a convenient way for me to inject Worker code onto somebody else’s website from within a userscript. This has also lead me to the discovery that it ought to be possible
to implement userscripts that inject Service Workers onto websites, which could be used to mashup additional functionality into websites far in advance of that which is typically
possible with a userscript… more on that if I get around to implementing such a thing.
Fetch
The final of the new technologies I’ve been playing with this month is the Fetch API. I’m not pulling any punches
when I say that the Fetch API is exactly what XMLHttpRequests should have been from the very beginning. Understanding them properly has finally given me the confidence to stop
using jQuery for the one thing for which I always seemed to have had to depend on it for – that is, simplifying Ajax requests! I mean, look at
this elegant code:
Whether or not you’re a fan of Javascript, you’ve got to admit that that’s infinitely more readable than XMLHttpRequest hackery (at least, without the help of a heavyweight library like
jQuery).
Other things I’ve been up to include Laser Duck Hunt, but that’s another story.
So that’s some of the stuff I’ve been playing with lately: Intersection Observers, Web Workers, Blobs, and the Fetch API. And I feel all full of optimism on behalf of the Web.
Easy cache & dash for my 3 y/o niece and I on the way back from a trip to Islip play area (and one of Islip’s multis) from our home in Kidlington. Super easy find, nice and fast. No
sign of the travel bug. TFTC.
Came out with my 3 y/o niece (and budding geocacher) to the play area across the road and took a diversion to come find this cache. Enjoyed finding the stages and reading/counting to
get the requisite numbers. GZ (from our interpretation of the coordinates) had an ‘obvious’ hiding place, based on previous Church Micros we’ve found, but our instincts were deceptive:
what we needed to be looking for wasn’t really ‘micro’-sized nor was it, as we’d initially suspected, magnetic!
Hint meant nothing to us (some kind of pop culture reference?) but previous logs that mentioned broadening the search helped us resolve to carry on searching despite the recent DNF, and
we evacuating found the container. We found it on the ground, but based on its design we don’t believe that that’s where it was supposed to be, so we returned it to the nearest location
for which its design seemed to fit. Logs slightly damp, not critical, but we weren’t carrying our repair kit so we weren’t able to do any maintenance.
A great idea for a multicache but might benefit from a better hint (it still makes no sense even after finding the cache!) and perhaps a better hiding place (based on the logs, this one
looks like it keeps getting disturbed).
Stopped off on the Southbound carriageway and took a walk over here to find this cache while I was nearby. Only had my phone and not my GPSr, which made finding this harder than I’d
like (my phone’s GPS is usually pretty appalling) but the hint made all the difference. GZ a little disgusting right now as clearly the walk across the car park to the services’ toilets
was too far for somebody (eww), made worse by this being the hottest day of the year so far (double eww). No sign of either travel bug – must have already been taken – which is a pity
because I’m sure I could have helped both along! Ah well! TFTC.
I just met somebody who was in the team that built this bridge (he was explaining about how the bridge is slightly wonky because the wrong kind of beams were delivered to the site). I
was thinking: that’s a great story, I’m going to put a geocache somewhere near that bridge. But yours was already there so I shan’t. Just thought I’d share!