If you try to fail, and succeed: what have you done?
It’s one of my favourite rhetorical questions, and one that I’m reminding myself of a lot more now that I’ve returned to practising Parkour.
The human body is, without any doubt, the most amazing machine ever invented. It’s like a great big physical neural network – whatever I put into it, it takes it on board and changes next sleep. A good friend once told me “whatever you’re doing right now – whether it’s running, swimming, sitting or lying down – that’s what you’re training your body to do from now on”, and the words are very true. This leads me into the topic I’m musing on this week: the idea of failure, and how it’s not always such a bad thing.
Yoda says: “Do, or do not. There is not try”, and we live those words in parkour. Every jump, a catch and vault must be fully committed to, it’s the only way to truly push our own boundaries. In the absence of try though, what does exist is “fail”. It’s amazed me how the parkour community – as well as a lot of other online communities – seem to have moved to concept of fail into a noun in its own right (to get an idea of what I’m talking about, check out any online forum like Sydney Parkour and do a search for fail: you come up with terms like “you’re full of fail”, “there’s fail in the water”, “the bitter taste of fail”, and even “the AIDS crabs live on fail”). In parkour especially though, fail has another meaning – a good one. Failing at something doesn’t just mean I didn’t succeed at it. It means I tried my all, fully committed, pushed my limits, and didn’t succeed at it. Not succeeding is the least of my worries – being fully committed, pushing my limits and trying my all is the key: those are the actions that improve my technique, increase my confidence, and most importantly – prompt my body to add enough flexibility/muscle mass etc. to get me closer every time.
In parkour, fail doesn’t just mean fail. It means pushing yourself one step closer to success next time.
The human body truly is an amazing machine, and pushing it to success – even if I might get a bit of fail on me in the process – is easily the most amazing thing I’ve ever felt a part of. It leads me to thinking that the human mind can’t be that different: that even if I can’t find that special solution, that phrase that’s just right, visualise that outcome or imagine the next step – so long as I’m trying my best, fully committing, and pushing my limits it doesn’t matter. I’m not failing to be successful, I’m succeeding to fail.
Physically or mentally, are you truly pushing your limits? Embrace the fail
Posted by Tatham
| Tagged: Musings
I’ve had these words written on a post-it on my work computer, and a scrap of paper blu-tacked to my home computer desk, for almost a year now. “What is Value?”
When I first put them up at the recommendation of David Deangelo, I didn’t really understand what they meant and as I write this blog I still don’t. The point of putting the words up is not to know the answer, but to always be asking the question from different contexts, first by asking what is valuable: “What is valuable to me?”, “What is valuable to her?”, “What is valuable to my boss?”; then by asking what being valuable, or not being valuable means, to simply ask: “What is value?” To me? To her? To my boss? etc. It was an idea that really appealed to me, and as I recently got reminded of the concept I wanted to share some musings on it.
The muse, in this case, was Batman. Or, to be more specific, my housemate playing Batman: Arkham Asylum. I watched him struggling and swearing and restarting his way through one of the final minion battles – one that I found disappointingly easy – and realised that over the course of the game, he never became particularly skilled at the controls. To me, a game like Arkham Asylum (which if you haven’t played yet – go get it right now!) offers a window to perfection: it’s technically possibly to go through the entire game without Batman taking a single hit, or at least only taking a few grazing body punches. To me that makes the game so much more believable that it becomes valuable to me to get skilled enough at the controls to play a believable game.
Of course, my housemate doesn’t feel the same way, and only ever became skilled enough at the controls to get through the parts he needed to. And it reminded me to ask myself: “What is Value, to him?”
What is Value to you?
Posted by Tatham
| Tagged: Musings
In one of the projects I’ve been working on recently, I needed to programmatically generate a geosphere primitive. I had some old almost-complete code for this purpose, but as I dug it up I discovered – like many of us do – that 3 years ago my coding style was horrible, and the code itself is cryptic.
So instead of modifying my own code, I went online to try to find the solution I would have based the code upon (and then not placed in the comments *smack*). But little luck, all my Google searches for geosphere algorithm, geodesic sphere generation and the like didn’t find me what I wanted. So I eventually decrypted my own code, and I’ll post it here for fellow lost travellers. I believe most of this comes from Paul Bourke, but I’m not sure of the origin of the icosahedron code.
The basic idea of a geosphere is quite simple: Take a 3D primitive, subdivide each of its faces over a number of repetitions to increase the resolution, then push every vertex out to the radius of the sphere you’re trying to approximate. Almost any 3D primitive is good for the job, but not all will ensure the resulting faces are equal sizes. I believe the best 2 primitives to use are either the Octahedron (8-sided) or Icosahedron (20-sided). While they won’t result in exactly equal faces, the difference is so small it’s never really noticeable. So, on to the code:
public Geosphere(float radius, Vector3 position, int depth)
This is all pretty straightforward. Let’s look closer at each method:
private void GenerateIcosohedron()
//Calculate variables for algorithm
float piOnFive = (float)Math.PI / 5.0f;
float piOnTen = (float)Math.PI / 10.0f;
float unitRadius = 1.0f;
float insideExtent = (float)Math.Cos(piOnFive);
float sideLength = 2 * (float)Math.Sin(piOnFive);
float Cx = (float)Math.Cos(piOnTen);
float Cz = (float)Math.Sin(piOnTen);
float H1 = (float)Math.Sqrt((sideLength) * (sideLength) - unitRadius);
float H2 = (float)Math.Sqrt((insideExtent + unitRadius) * (insideExtent + unitRadius) - insideExtent * insideExtent);
float Y2 = 0.5f * (H2 - H1);
float Y1 = Y2 + H1;
float r = unitRadius;
float s = sideLength;
float h = insideExtent;
//create the icosahedron
Vertices = new List();
Vertices.Add(new Vector3(0, Y1, 0)); //a
Vertices.Add(new Vector3(0, Y2, r)); //b
Vertices.Add(new Vector3(Cx, Y2, Cz)); //c
Vertices.Add(new Vector3(0.5f * s, Y2, -h)); //d
Vertices.Add(new Vector3(-0.5f * s, Y2, -h)); //e
Vertices.Add(new Vector3(-Cx, Y2, Cz)); //f
Vertices.Add(new Vector3(0, -Y2, -r)); //g
Vertices.Add(new Vector3(-Cx, -Y2, -Cz)); //h
Vertices.Add(new Vector3(-0.5f * s, -Y2, h)); //i
Vertices.Add(new Vector3(0.5f * s, -Y2, h)); //j
Vertices.Add(new Vector3(Cx, -Y2, -Cz)); //k
Vertices.Add(new Vector3(0, -Y1, 0)); //l
//create the indices list
_IndexTriangles.Add(new IndexTriangle(0, 1, 2));
_IndexTriangles.Add(new IndexTriangle(0, 2, 3));
_IndexTriangles.Add(new IndexTriangle(0, 3, 4));
_IndexTriangles.Add(new IndexTriangle(0, 4, 5));
_IndexTriangles.Add(new IndexTriangle(0, 5, 1));
_IndexTriangles.Add(new IndexTriangle(1, 8, 9));
_IndexTriangles.Add(new IndexTriangle(9, 2, 1));
_IndexTriangles.Add(new IndexTriangle(2, 9, 10));
_IndexTriangles.Add(new IndexTriangle(10, 3, 2));
_IndexTriangles.Add(new IndexTriangle(3, 10, 6));
_IndexTriangles.Add(new IndexTriangle(6, 4, 3));
_IndexTriangles.Add(new IndexTriangle(4, 6, 7));
_IndexTriangles.Add(new IndexTriangle(7, 5, 4));
_IndexTriangles.Add(new IndexTriangle(5, 7, 8));
_IndexTriangles.Add(new IndexTriangle(8, 1, 5));
_IndexTriangles.Add(new IndexTriangle(11, 6, 10));
_IndexTriangles.Add(new IndexTriangle(11, 10, 9));
_IndexTriangles.Add(new IndexTriangle(11, 9, 8));
_IndexTriangles.Add(new IndexTriangle(11, 8, 7));
_IndexTriangles.Add(new IndexTriangle(11, 7, 6));
I wish I knew where I got this code from. I believe the vertex generation stuff is from Paul Bourke, while I calculated the indices myself. Note that I’m using an IndexTriangle class to store the indices. This makes it easier to subdivide the triangles in the next step. I’m also assuming the icosohedron has a unit radius (1.0f), because I’ll be pushing vertices out to the radius lateron.
private struct IndexTriangle
public IndexTriangle(int a, int b, int c)
this.a = a;
this.b = b;
this.c = c;
public int a;
public int b;
public int c;
The next step is to subdivide each triangle and repeat to a desired depth. The subdivision I’m using splits each triangle into 4 smaller ones like so:
private void SubdivideToDepth(int depth)
for (int i = 0; i < depth; ++i)
List newIndexTriangles = new List();
foreach (IndexTriangle indexTriangle in _IndexTriangles)
Vector3 newVectorOne = Vector3.Lerp(Vertices[indexTriangle.a], Vertices[indexTriangle.b], 0.5f);
Vector3 newVectorTwo = Vector3.Lerp(Vertices[indexTriangle.b], Vertices[indexTriangle.c], 0.5f);
Vector3 newVectorThree = Vector3.Lerp(Vertices[indexTriangle.c], Vertices[indexTriangle.a], 0.5f);
IndexTriangle newTriOne = indexTriangle;
newTriOne.b = Vertices.IndexOf(newVectorOne);
newTriOne.c = Vertices.IndexOf(newVectorThree);
_IndexTriangles = newIndexTriangles;
And finally, push all the created vertices out to the radius, so we end up with the approximation of a sphere
private void PushVerticesOutToRadius(float radius)
List newVertices = new List();
foreach (Vector3 vertex in Vertices)
float rootrad = (float)Math.Sqrt(vertex.X * vertex.X +
vertex.Y * vertex.Y +
vertex.Z * vertex.Z);
newVertices.Add(new Vector3(vertex.X * (radius / rootrad),
vertex.Y * (radius / rootrad),
vertex.Z * (radius / rootrad)));
Vertices = newVertices;
The code is looking pretty ugly posted up at the moment, hopefully I’ll have time to tidy it up tonight.
Posted by Tatham
| Tagged: Coding
In my time owning an iPhone I’ve bitched and ranted, jailbroken, tethered, updated and created, replaced and mis-placed it. I’ve also typed a lot of messages on it, and sometimes the built in dictionary suggests some pretty strange corrections.
While I certainly can’t say I’m the most grammatically correct SMS writer, I certainly expect my dictionary to be. But here are 10 suggestions the iPhone has made that I’m pretty sure aren’t actually words at all:
What I was trying to write
||I keed, I keed
* (not me, a friend was typing that one in. Honest!)
Posted by Tatham
I’ve already made plenty of mention about my disappointments with the iPhone, especially Apple’s Machiavellian approach towards the platforms development. And their AppStore policies – deliberately unpublished, unknown and unquestionable – are, to be quite frank, pretty questionable (see this story of an app rejected because users could type curse words into a text box, and the ridiculous rejection of Flower Garden Lite for not having features it actually had). But today I’m bitching about something else – its worth as a smart phone to me and my fellow laptop-carrying net-addicts.
For me 3G is all about using my phone as a modem for my laptop, and hooking into high-speed internet wherever I travel in Sydney. Once I traded up to an iPhone, these dreams were quickly killed. While PDANet got me through the interim, the release of firmware 3.0, with USB and Bluetooth tethering was what I was truly waiting for. After downloading it and checking it out though, I found myself sorely disappointed.
Let me start by saying that Bluetooth tethering is wonderful. I can use my iPhone to connect to the internet without even taking it out of my pocket, and the slight speed trade-off is definitely worth it. Well, when it works.
I find myself having to acquire a new IP address every time I connect through my phone, making the whole process less ‘connect and go’ and more ‘connect, reconnect, repair, kick it a bit, and I can limp off’. Once connected I can only get a good 10-15 minutes worth of browsing in before Optus Mobile’s DNS server caves in from the pressure of being asked to do stuff and quietly ignores me. And if I ever get a call while browsing, well the whole phone dies in a fiery blaze. Not only does tethering turn itself off, it disables itself and completely locks me out of turning it back on.
Of all these myriad issues, the most annoying by far is Optus’ DNS. When the DNS silently dies on me, it kills my iPhone internet connection as well as the laptop tethered one, so my email starts to mount up without me realising. Being the techie I so often claim to be, I thought: “this should be easy enough to solve, I can just use an OpenDNS server instead of Optus’ poopy one”. Changing DNS for iPhone is not a walk in the park though.
Being that iPhone inherits much from Unix, my first thought was to edit the nameservers in the etc/resolv.conf file into OpenDNS ones. Oops! etc/resolv.conf is actually a symlink to var/run/resolv.conf. Okay, I’ll edit that file. Hmm, it doesn’t exist. Undeterred, I simply removed the symlink and created my own resolv.conf with the nameservers I wanted. Still no good, seems Apple doesn’t even use the resolv.conf files at all.
For now, the efforts to overcome more shortcomings in the iPhone continue. But I wanted to say this before I continue:
”You know what really grinds my gears?
Posted by Tatham
A friend and I have started work on a new game project recently, and amidst the early brainstorming came up with an idea we both found interesting. Over the course of our free time in the next couple of days we mocked up a quick gameplay prototype using XNA.
On an aside, I think I’m in love with XNA. It’s so nice to be able to just have a sample project drawing to the window up and running straight from the start, and just be able to go straight into prototyping the stuff that matters. I’m sure my familiarity with C# over the last year has certainly helped fuel this fleeting love affair, and although seeing things like recursion used to run the game loop worries me (here lies my game, killed by foreseeable stack overflow), I’ve definitely decided to use XNA to develop the full-game version of Space Billiards.
Anyway, I digress. It’s been a lovely change to actively collaborate on a class-by-class, design and concept level with someone on an idea, and has really pointed out to me what I’m missing by holding a higher-paying but non-games job. It was freeing to sit down and really let my inner programmer out. It was……disappointing when the prototype wasn’t any fun
See, this is why we prototype. It might be a fun-sounding concept, it might be great fun to create, but in the end it’s a game, and if it aint fun, it aint worth playing. I remember reading an opinion on of the Gamasutra columns about game design, which I will now horribly metaphorically mangle and paraphrase: If all the possible gameplay concepts and games that could be made from them were laid out as a rubber sheet and then lifted up by how ‘fun’ they are to play (to the more savvy, imagine a 3D graph with ‘fun-times’ as the Y-axis), then there’d be many varying heights, gradients, and bases in the mountains that would result. When creating a game idea, I’m essentially shooting at a random point on that plane. Might be on a small hill, on a very high mountain, or right in the middle of an ‘unfun valley’. And while new iterations over the game design to increase the fun factor always help, the limit is really defined by where on that plane my original idea was.
How do you tell how fun a game ‘could be’? I’m not sure. Experience mixed with knowledge mixed with a bit of guesswork I suppose. Our prototype barely rated 2/10 on the fun-ometer, our guess is we could probably push it to a 7 or 8 by tweaks and changes. How correct we are…..well, I guess time will tell that
Posted by Tatham