Lessons Learnt From the First Job I Ever Quit

What I learnt about myself from my time at Trinity Mirror

On 4th September 2005, in God’s great sovereign
plan, I started work as a software engineer in the Digital IT department of the
Trinity Mirror newspaper group,
working on their online titles. It was a surprising move, in some ways: my
passion has always been for computer graphics and games development, and it’s
fair to say that web development had only ever been a sideline for me up until
that point. My priority at the time, however, was to get a reasonable job that
would enable me to still have a life outside of work so that I could get
involved in a church where I’d be
built up and equipped to serve Jesus in the long term, and Trinity Mirror
seemed like it would offer that. In the event, it exceeded my expectations in
every way, and any doubts I may have had quickly vanished. As a green young
developer with little experience of the realities of programming in a real-world
team it was a privilege to work with the very talented group of developers they
had working for them, and I shall be forever grateful for the masses I learnt
there about how to make great software, working on sites like Adzooks.co.uk and the rebranded Liverpool Echo and similar regional
newspaper sites. They taught me the joys of agile methodologies like Extreme Programming and Scrum; they taught
me the importance of actually talking to your customers and not just assuming
that you know that they want or even that they know what they want; they
taught me how (and how not) to write maintainable code (or at least why it
matters!); they certainly taught me the utterly incomprehensible choice of a
language that is Coldfusion;
but above all they instilled in me a deep routed desire to avoid the cheap and
easy hacks and implement the right solution in the right way.

So what changed?

For various reasons I’ve been getting increasingly itchy
feet for some months now, wanting to move on from Trinity Mirror. Whilst it’s
not appropriate to go into the details here of exactly why, I’d like to share
with you the following lessons that I’ve learnt about myself through the perspective
of my growing discontent:

  1. I’m a sinner. My colleagues will
    have had no problems identifying my many flaws, although I suspect they
    might think nothing of that which I consider most serious: my lack of
    thankfulness to God. It’s a testament to the depths of human depravity
    that when there were so many absolutely awesome things about this job I
    still managed to grumble my way through my last few months.
  2. Building something people want is way
    more interesting than exposing them to more advertising
    . Paul Graham
    is always going on about the fact that the best way to make wealth is to
    build something people want
    , but I’ve discovered through experience
    that it’s also the most satisfying kind of work I’ve ever done. I’ve only
    really just worked out why it was that working on Adzooks.co.uk was consistently the
    most interesting and enjoyable aspect of my job, and it’s this: when
    working on Adzooks, we were focussed on giving end users a more useful and
    more satisfying experience, often without any clear means of monetising
    it. The less satisfying projects were the exact reverse. There are some incredibly boring ways to
    make money
    out there, and also some awesome products with no strategy for making money whatsoever
    – but they’ll find a way some day. If I didn’t already, I certainly know
    now which of those I’d rather do for a living.
  3. I work best when my productivity
    levels are easily seen
    (for better or for worse). This is really a
    corollary of number 1 – I’m a sinner, who is both lazy and proud, and my
    behaviour in the face of changing circumstances has revealed that ugly
    truth. The loss of a great manager who was always aware of what I was up
    to and gave frequent feedback; a growing team where the contributions of
    individuals is harder to spot; a form of Scrum where the perception is
    that as long as you deliver what you committed to at the start of a
    fortnight there’ll be no questions asked – all of these things slowly
    began to sever the connection between how hard I worked and my standing
    within the team. The standard set for me is to “obey in everything those
    who are your earthly masters, not by way of eye-service, as
    people-pleasers, but with sincerity of heart, fearing the Lord” (Colossians
    3:22
    ), and yet instead people-pleasing seems to so often be the
    driving motivation, with sincerity of heart barely getting a look in. It’s
    easy to work hard when people will praise you for it; it’s far, far harder
    to keep pressing on when the hope of the Lord Jesus’ commendation is the
    only motivation on offer. On judgement day I shall have no defence but to
    plead the blood of Jesus who died to defeat such sin – and praise God for
    such a hope! For one day, by his grace, this sinful nature of mine will
    be overcome, and I shall be free to serve him perfectly as I long to
    do. In the mean time, give me small teams! Give me feedback! Give me high
    visibility of my productivity.

Finally, do I have any parting words for my co-workers?

  1. A huge “thank you” for everything.
    You’ve been great. It’s been marvellous fun. We’ve drunk a lot of tea.
  2. Be the change you want to see in the
    codebase
    . Don’t just grumble about the state of legacy code, get on
    and refactor it. Live the dream! Make things just a little bit better
    every day, placing your mark on the world. Be a garlic
    programmer
    .
  3. Never be content with mediocrity.
    You’re all smart, talented people. Yes, even you. Don’t settle for things
    the way they are – always be looking for ways to make things better. Read
    everything and anything you can get your hands on – you’ve got some great
    books on that shelf of yours! Question everything – why did that break? What could I have done differently to
    prevent it? What am I going to
    do differently to prevent it happening again? How will this change I’m
    about to make affect how hard this code is for other people to maintain?
  4. Make plans for eternity. Jesus may
    seem like a humorous joke to you at the moment, but one day you will die,
    and on that day you will meet him as your judge. “Of this God has given
    assurance to all men by raising him from the dead.” (Acts
    17:31
    ) I know it seems unlikely, but if it’s true then it’s so
    profound that it changes everything
    – isn’t that worth spending a few hours of your life to at least look into
    it?

Farewell, Trinity Mirror!

Tips for taking over someone else’s code

I’ve been dying for some time now to write a post explaining some of the changes I’ve been making to Blender’s DirectX exporter. In some senses it’s nothing particularly exciting, but it’s been a great learning experience for me, and it’s unearthed some little nuggets of goodness that I just can’t help but share.

The Importance of Feedback

I’ve been developing an engine to make 3D Point & Click adventure games for a few years now, and I have to admit that for much of that time I’ve been in a state of denial about how hard it would be to get content out of my 3D modelling package, Blender, and into my game. I’d only ever used pre-existing .X files for all my testing (good old Tiny.x!) and since Blender ships with a Python script for exporting DirectX files I wrongly assumed it be trivial to start creating my own when the need arose.

exporter_20080404.jpg

However, when I eventually tried it, it seemed to fail every time. The author was great at replying to my emails, and he was always able to diagnose some obvious flaw in the way my mesh was configured that was causing the exporter to stumble – “you’ve got a negative scaling factor”, “your armature isn’t parented to the mesh properly”, “you’re using envelopes instead of vertex groups for skinning”, and so it went on. These things were obvious to the author, since he knew exactly how the exporter worked and what assumptions it made, but to someone like me who’d never delved into the source code, all I knew was that my mesh wasn’t working properly and that I wasn’t being given any feedback to help diagnose the problem.

There’s a lesson in there: never let your software fail silently. If your user has ticked the “export animations” button, there’s a good chance that they think their mesh contains some animations. So why not check that you agree? If their mesh doesn’t contain any vertex groups that match bone names, and your code is built on the assumption that there are, it probably wouldn’t hurt to tell them.

The Mystery of Someone Else’s Code

Eventually I realised that I couldn’t rely on the author debugging my meshes for me forever, and that I was going to have to get my hands dirty to figure out why my mesh wasn’t working. I very quickly discovered what people have been telling me for years: it’s far, far harder to read code than it is to write it. I wasn’t helped by the fact that I’d never written a line of Python before in my life, nor did I have any knowledge of the Blender API. To be honest, I really rather enjoyed the challenge of figuring out this mysterious piece of code. Here are some of the tricks I used in my siege upon the citadel of mystery:

  • Treat every line of code other than the one you’re actually interested in as a black box that you don’t need to understand. This was helped by the fact that the exporter was nicely broken up into lots of beautifully short functions, so to begin with I could ignore all of them except the entry point. I’ve seen plenty of people give up and go home because they wanted to understand a complex system in its entirety, and the challenge was just too great. Gradually, over time, strongholds began to fall as I captured functions into my empire of understanding
  • Rewrite the code where necessary so that it documents itself. Many of the functions and variable names were either unenlightening or plain misleading. Here’s an example: the exporter gives the user two buttons, “Export All”, and “Export Selected”; which of those buttons do you think the ‘SelectObjs’ method belongs to? Well, for some unfathomable reason, that’s the function that exports all objects. Rename it! I’m a strong believer in having plenty of comments, but I’m an even bigger advocate of the idea that the code itself is the best explanation of what the code does (it’s certainly the easiest to keep up to date!) so it should be made as readable as possible by using sensible function and variable names. Got an argument called ‘obj’ which is always a ‘Mesh’ object? Rather than adding a comment to the code, why not rename it to ‘mesh_obj’ so that it comments itself? Conversely, if you have a variable called ‘mesh_obj’, make sure it doesn’t sometimes contain an ‘Armature’ object!
  • Liberal use of debug output – whilst you’re in the process of understanding some code, don’t be afraid to make it output all manner of superfluous debug information to help you get a feel for what values your variables hold at different points. Similarly, it’s helpful to explicitly document what assumptions you think the code is making about the contents of its variables (in C++ I’ve started to use ‘assert’ for this a lot more than I used to). Sometimes I’ve even used this in cases where you think it can’t possibly be necessary, and unearthed some really obscure bugs – for instance, if you’re convinced (and relying upon the fact) that two expressions are equivalent (e.g. you think that parent_matrix * my_matrix = combined_matrix) then by outputting the two expressions you can get a very helpful clue when you realise that they’re actually different.

Making it your own

Having started to understand the code a bit better, I gained the confidence to start making some improvements of my own. Here are some of my favourites:

  • ‘Why’ not ‘how’ – the original version of the code contained a good dozen instances of this line: name.replace(".", "").replace(" ", "_"), to deal with the fact that object names inside a .X file can’t have dots or spaces in them. Now, in some ways this seems harmless enough, but I wanted to factor it out into a method call anyway, just because I’ve got a strong dislike for ‘copy and paste’ coding. I could have named the method, “remove_dots_and_spaces” (a ‘how it does it’ name), but I’ve come to realise that a semantically descriptive name is much more useful, so I called it “make_x_compatible_name” (a ‘why it does it’ name). By doing that, it got the creative juices flowing, and I started thinking about what else might cause a name to break your .X file, and came across an example where using a reserved word (e.g. ‘string’ or ‘integer’) as a name caused it to break. Having a method factored out made it trivial to add some code to check for reserved words, and the change then immediately applied everywhere that method was used. Fantastic!
  • Pythonesque-ness – I can’t say for sure, but one got the impression reading this code that, like myself, the original author wasn’t a native Python speaker. I had great fun and learnt all sorts of neat things by rewriting things to be as Pythonesque as possible. I think so far my favourite Python feature is list comprehensions – the ability to generate new lists based upon old lists in a single line of code, a sort of combination of map and filter all in one neat piece of syntactic sugar. In my view, rewriting the code to be more ‘natural’ Python makes it a lot more compact and readable – it allows the intent to show through more clearly without being distracted by the means.
  • More robust error handling – I’ve added a great deal of code to the exporter that spots problems with how your mesh is configured and reports back to you. Hopefully that means it will be a lot more useful for real life work by real life people. One of my goals was to fix anything within the exporter that would require ‘fiddling around’ by the artist, since code in the exporter only needs to be written once whereas there are a lot of 3D assets to be made, and the exporter needs to be run again and again.

You can find my version of the exporter here. If you do experience any problems with it, please report back and send me your .blend file so that I can continue to improve its error detection and feedback.