Monument Valley

Monument Valley – Ida

Monument Valley is a puzzle game for iOS (and soon Android) that tasks you with helping Ida on her journey through the ruins of a colourful, geometrically impossible kingdom.

This is a beautiful game - the art style is minimalist and polygonal without being difficult to interpret and it looks as though every pixel was carefully placed, even when you're manipulating the world by rotating towers or pulling at parapets to make new paths.

And the games' sound design is great as well, subtle sound effects make the world feel tangible, and when you slide your finger to pull a platform you hear feedback in the form of gentle, relaxing musical notes.

The world is filled with optical illusions like Penrose triangles and platforms that only align from a certain angle, where the perspective of the player determines whether a path is walkable or not.

Monument Valley – a rotating platform creates a Penrose triangle

Perhaps the most impressive part of Monument Valley is that it never feels too difficult. I don't think many people will be tempted to stop and come back to it later because it's too hard, or find a particular puzzle so frustrating that they'll want to look online for a solution (although I did have to stop and think for a while on the later levels), but equally the puzzles never feel unsatisfying either.

Monument Valley – waves batter a tiny island

The game only takes about 2 hours to complete (to be honest I lost track of time while playing) but still manages to tell a story – not a very complex story, and a lot is left to the imagination, but I still felt moments of joy and sadness as I helped Ida on her quest.

In summary I loved Monument Valley. It's a great game, definitely worthy of the price in my opinion, and I'm looking forward to seeing what else ustwo games come up with in the future.

Visualizing Git Concepts with D3

Visualize git with d3

I love this visualisation of git! It's really cool being able to actually see the difference between commands.

I recommend trying both a git pull and a git pull --rebase on the git fetch example.

I also noticed in the "Update Private Local Branch with Latest from Origin" example that you can rebase your branch against master without pulling master. Doing a git fetch and then a git rebase origin/master is all that you need. I've always checked out and pulled master explicitly. Good to know!

Maps + video from space

Mapbox have combined their Streets map with this footage captured from Skybox's SkySat-1.

There's a discussion on Hacker News about the difficulties and implications of the technology.

Aelita

Aelita

Today at the Zendesk Dublin office we had a Hackday, and David, Alan and myself built this web-based "soyuz"/monome clone, that we called Aelita.

It was a lot of fun, even though we were the only group in the office that didn't build something practical!

The source code is on github, let me know what you think.

WebGL Raytraced Eye

WebGL raytraced eye

This WebGL eyeball looks amazing, it's so cool that this is possible in the browser now.

Fill Murray

Bill Murray

Placeholder images of Bill Murray by Dave Cowart.

(Via Marc Lloyd)

Build with Chrome

A Lego Viking Tour Bus in Dublin

Today I've been playing with this amazing toy from Lego and Chrome that lets you build Lego models on Google Maps. I found this great rendition of a Viking Tour Bus/Boat in Dublin's Grand Canal Quay. (For the record this is what they actually look like).

So cool!

(Via Kill Screen)

Chineasy

Image of the Chinese phrase for 'dormant volcano'

Above is the Chinese phrase for dormant volcano.

Chineasy’s goal is to allow people to learn to read Chinese easily by recognising characters through simple illustrations. The magical power of the Chineasy method is that by learning one small set of building blocks, students can build many new words, characters, and phrases.

(Via Wesley)

Blog Redesign

Recently I've felt like writing again, but I've felt frustrated with the way that my blog is designed, both in terms of how it looks and how it functions.

I started paulboxley.com in 2010 as a link dump – almost all posts were very short, usually consisting of just a link to another website, an image and a line or two of text.

I chose a 'masonry' style layout as it fitted the kind of content that I tended to post – a kind of personally hosted Pinterest.

There could be any number of columns depending on the width of the user's browser, and individual posts would span either one, two or three of these. Smaller posts would be nestled in around the larger ones.

The design was adequate when I only had shorter posts, but problems arose when I wrote longer blog posts – the smaller posts laid out around the edges would distract from the content of the main post.

New columns

I decided it would make more sense to switch to a new layout, and after a few experiments I opted for a three-column layout (degrading to two or one columns on smaller browser windows, but only ever three columns maximum).

Blog posts that I want the reader to focus on now take up all three columns, and link posts take up a single column.

Aside from the layout, the design of the website also needed refreshing, and I have to thank Jonathan Belton for his expert advice in this area! If there are any elements of this site that you think look great then please presume that they were Jonny's idea, and you can likewise presume that any parts that look less good are ones in which I did not listen to Jonny's advice. ;)

I've also made some other changes under the hood. Previously blog posts were stored in files in the git repo which kept things simple, but meant that I couldn't write new posts unless I was near a terminal. Now I'm using a database so I can write and edit posts in a browser (wow, it's like I'm in 2001)!

I'm also toying with the idea of adding comments to the site with something like Disqus. I would prefer if there were a straightforward way to integrate tweets-as-comments, but I'm not sure if such a solution exists. If you know of anything then please tweet me @baxt3r.

I hope you like the new design! Please let me know if you encounter any bugs or problems, and I hope to write again soon. :)

An angle bug

I discovered a bug in my previous Boids post. To rotate a boid I was doing this:

If current direction angle < target direction angle
  Increase current direction angle
If current direction angle > target direction angle
  Decrease current direction angle

Which seemed reasonable enough, but I hadn't considered the way that angles are calculated.

In javascript all angles use radians. You may remember that there are 2π radians in a circle. Within HTML5's <canvas>, radians have the following meanings:

  • 0 radians means you are pointing East
  • ½π radians means you are pointing South
  • −½π radians means you are pointing North
  • π or −π radians means you are pointing West

Examples of all the angles

(Radians weren't the problem here, I would have had the same problem if javascript had used degrees)

The problem that I was seeing was that sometimes a boid would be travelling South West and its target would be North West of it, but rather than turning clockwise it would turn anti-clockwise.

Here is a boid being told to rotate to and from a direction in the South West and a direction in the North West, because an example is often more helpful than an explanation:

As you can see, this boid is taking the long way around.

What's going on?

The boid stores its direction as a number which reflects the angle in radians that it should be facing. If it starts at +3.0 radians and we instruct it to move towards −3.0 radians then it will follow its simple instructions:

If +3.0 > −3.0
  Decrease current direction angle

+3.0 is greater than −3.0, so the boid decreases its current direction angle, moving from +3.0 to +2.9 to +2.8 to +2.7, which turns it anti-clockwise, going through the zero point and sending it the long way around.

What we'd expect to see is the boid taking the short route between the two points, through π (remember +π and −π mean the same thing in this situation).

Why is this a problem?

As far as bugs go this isn't the end of the world, but it results in some undesirable behaviour.

If there are two boids, A and B, with directions of +3 and −3 respectively, when they come close to each other we would expect them to match directions, averaging to +π/−π (remember that +π and −π mean the same thing). What will actually happen is that the two boids will change direction away from each other, trying to average at 0, which is almost the opposite to the direction they're currently travelling in.

In a more general sense it makes it far less likely that a flock of boids will end up moving in a Westward direction.

How do we fix this problem?

We need to treat the direction more intelligently. Rather than just treating it as a number we have to recognise that it's an angle and that +3.0 is actually closer to −3.0 than it is to 0.

In order to find the difference between one angle and another we can say:

difference angle = end angle − start angle

But this only works if the two angles are either both North of 0 or both South of 0. If the two numbers are on opposite sides, say +2.0 and −2.0, then the result would be beyond either π or −π, in this case −4.0.

We can easily fix this though: we know that a circle has 2π radians, and that in HTML 5 canvas the semi-circle from East to South to West goes from 0 to +π, and the semi-circle from East to North to West goes from 0 to −π, so once we go beyond either π or −π we can just subtract or add 2π to that number to get a more reasonable number.

difference angle = end angle − start angle
if difference angle > π
  difference angle = difference angle − 2π
if difference angle < −π
  difference angle = difference angle + 2π

Now the result of passing in +2.0 and −2.0 will return around 2.28

Find difference between current direction and target direction
If the difference < 0
  Increase the current direction
If the difference > 0
  Decrease the current direction

Replacing this part of the code leads to the following behaviour:

Which looks much better. Problem solved!