It’s not often (never) that I feel moved to review a computer game. It’s not so much that I don’t play them, because I do – quite a bit sometimes, but because they are generally “good” and an awful lot of people already review games.

Enter TIS-100; it’s a modest little thing, and it’s interface is both nostalgia-inducing retro and modern convenience. It looks like you should be using an ancient IBM model M keyboard, but actually allows mouse clicks and control-c/v commands just like modern software would. With very little fanfare you’re dropped into a broken operating system, where the corrupted segments of the kernel have to be fixed up by you.

Welcome to TIS100
Here’s the welcome screen – feel that 1970’s vibe.

The first part of the charm here is that there is no hand-holding. None. You’re provided with a short manual detailing the valid processor op-codes, a little brief on how the node based architecture works – and then you’re out in the wild. Each node has a short code limit of around 15 lines, and each node also allows access to two registers. And that’s it. You’re set a task, and provided with some tests to run with the expected output detailed on the left hand side of the display. This is coding stripped down to it’s barest nuts and bolts.

Part of the novelty is that the TIS stands for Tesselated-Intelligence-System – processing is divided out into separate nodes, each with their own codebase. Calls to access the values of other nodes block the callee, making simple swaps a more considered operation and deadlocks ever present. Once you’ve got the swing though, you quickly find that you can use nodes for parallel processing, or as quick scratch-RAM for a main processing node. Each task that you are set to repair a segment is also non-trivial, in that it’s a real operation you could expect to find in an embedded environment (signal peak detection, pattern matching – even an interrupt handler), and that there’s a genuine sense of accomplishment when the output column of the test matches the required values – and it’s extremely instructional.

Tis Running
A mid-level problem solved in drunken enthusiasm

I spend most of my working life dealing with a fourth generation language, and I’m abstracted away from the hardware by a considerable degree – but I’ve often yearned to get some assembly coding done (even maybe start a hobby operating system), and all of my attempts to “get in” to assembly have been thwarted. Either I wasn’t experienced enough, the documentation was patchy, or the build environment wasn’t sane; I’ve had several cracks at learning – but nothing in my twenty-plus years of developing has been as useful or informative as a (slightly drunken) hour with this little beast.

One of the joys is that coming from some much (.NET, SQL server) down to this level forces you to do far more with far less. I tend to float up objects and variables with wild abandon, expensive database queries and non-optimal execution trees don’t consume a lot of my thinking time because modern machines are so fast and have so much RAM.  I do sometimes go back over old code to correct my more egregious assumptions or requests (when they pile up into seconds), but here we’re given two registers two work with – and one of the register operations is destructive. Suddenly we’re up into The Art of Computer Programming territory, using a notional system to achieve realistic results – and with such little room to manoeuvre that optimisation is almost impossible to avoid.

This really has helped me enormously in terms of my feeling of “completeness” as a developer, and has refueled my desire to work through the Art of Computer Programming and GEB (Godel, Escher Bach – an eternal golden braid to the unfamiliar) – it’s the same feeling you get when a beautiful algorithm unfolds in your head, and when it gets down to it, it’s one of the reasons I’m in this business. I love to code, and I love good code – but we don’t often get paid to write good code; just stuff that works. If you feel the same then get this game, because it will put you back in touch with that feeling.

If you’ve never coded before, you may need a little more time bootstrapping yourself – but I reckon that you’d be far better off spending a day puzzling over this than almost any “fundamentals” programming course. This will get you in at the sharp end, and the techniques you learn will give you a better understanding of what various library functions do, their overhead – and insight into how much has gone into providing all that padding for you to keep you safe from the sharp edges of the hardware.

Please – go buy. It’s only a fiver, and I want to encourage the developer to keep adding more segments and more challenges; they’ve managed to re-awaken my hidden low-level developer, and I want more!

Racism – The War

This is a heavy post for me, but recent events have brought this subject closer and closer to my forebrain and it’s no longer ignorable – let’s talk a bit about racism.

First, a bit of context. I was born in a small village just North of Nottingham, and my first memory of someone who wasn’t the same race as me comes from when I was four. There was a kid in my class who’s family was from China, and because of my upbringing I treated him no differently from any other child – we played, we argued and we plotted against the teacher. Normal stuff. It was only when I got a little older and stayed paying attention to what adults said that I realised that some people around me didn’t just see another person, that people were making assumptions about him and his family based on nothing more than his origin. It annoyed me, because he was a playmate – but I didn’t tackle it as I would now. Throughout my childhood, my teachers explained things like racism and homophobia as though they were things from a prior age, as though humanity was on the cusp of finally growing past all that sort of thing. Imagine my disappointment to find thirty years later that if anything the situation is worse.

Foreign Business

I continued to grow up despising racism, but I never really engaged in doing anything about it; up until now you could say I was a noncombatant in the race war – and let me be clear on this – a war is what it is. Now I choose to fight in that war, and to do so I first need to be specific about the term racism. I have to admit I am not an expert on the subject by any means, but my working definition of racism is not limited to racist words; instead it is any action that seeks to obtain or maintain power over people of different race. I’ll skip over the obvious things (use of language to keep people “in place”, socio-economic discrimination), and even cast a jaundiced eye on “positive discrimination” – which is at worst a kind of patronage, a way of saying that people need to be dependent on you.

Racism is a part of the whole culture. While I certainly don’t think I should be held personally to account for the sins of my forebears, I do bear responsibility for allowing my culture to continue oppression and withholding privilege. We – now – get to make the decision about what we tolerate and what we don’t. Friends act in racist ways? Educate or reject them. Business operates on racist principles? Educate or leave. Family behave in racist ways? Educate or disown them.

If it’s not obvious from the first reading, I’ll make it clear why that makes it very difficult (impossible?) for anyone in the Western world of a different race to be racist to a white man. It’s because in the vast majority of cases, the person kicking out is not in the position of privilege; and taken as a whole their race certainly isn’t. If you look at any extant source of authority or power structure in the county (business, council, bank, etc.) you can bet that the members that form that authority are overwhelmingly white, and deliberately or not power structures tend to make change very difficult. If you’re white and someone tells you you can’t dance, that’s nothing but the truth – it’s not racist because it doesn’t perpetuate a culture of dominance over you, it’s not racist because it doesn’t remind you of hundreds of years of institutionalised disadvantaging of your people, and it’s not racist because it doesn’t make you lose hope in the chance of change.

Being a noncombatant is easy, because all it requires is inaction – but by being so we allow the continuation of something that should disgust anyone with working braincells, the deliberate suppression of an entire section of society. If you’re not fighting, it won’t change – and why wouldn’t you want it to change?

“One day people of X race may outnumber us?” – so? We’re all just people. We want to live, we want to have sex and we want a decent world for our kids. If the power dynamic switches sides, we should hope we are treated with more wisdom than we treat others. Humans are humans and that’s all that matters.

“I’m not racist, but” – yes you are. No excuses. My bullets in this war are for you. If you ever hear this phrase and don’t challenge it then you are dodging your responsibility in this fight – it doesn’t matter if they’re a friend or a family member, war transcends that and to ignore that fact is cowardice.

“I’m not privileged, I have X and Y disadvantage” – great, so you excuse yourself because you have some specific disadvantages rather than being held down by the weight of an entire society. Grow up and deal with your problems and stop blaming others.

“Oh well – bloke X is of race Y and he’s a terrible person” – Again, well dodged – there are good and bad people in every type of human on this planet, and saying that individual examples cherry-picked from your choice of 7 billion people excuse your reaction to any racial type of them is obvious idiocy.

That’s my opening rounds fired, I hope they do some good. The only way this war ends is by never believing it’s been won, and the first step of that is acknowledging it.

Coding Chickens

In a short break from our usual programme (while I finish writing up the details of my fast), I feel the need to explore some of the horrors developers face; if only to make myself feel a bit better.

Sometimes being a developer is rewarding, sometimes you get the strong feeling that you should be able to do more to help. Sometimes you get the feeling that you just can’t get people to understand that you are trying to help. You’re not giving long time estimates out of a desire to be difficult, you’re not trying to make something “sound more difficult than it really is”. You’re just trying to help.

Nowhere do I bump into this more than when managers congregate to work on ‘systems’.

A system is a nebulous thing, or at least it is before someone like me gets involved – I’m a systems developer, so I think in terms  outcomes and inputs, and minimisation of interaction. My job (which I am ok at, or so I’d prefer to think) is to take the fluff of a user requirement and turn it into a practical improvement. This unfortunately means that I bump into a lot of people who also believe that they can create systems.

I have the opportunity to watch this process of creation from a short range, and in one of the businesses I’ve dealt with for a very long time the effect is similar to watching a small clutch of argumentative chickens trying to work out a mirror. This mental image is far more amusing in the mind than it is in the flesh – as someone who really wants to improve an overall work environment, phrases like “Oh, I think we should have another form filled in and scanned before we let users do that” make my blood boil. At the end, there’s a lot of noise, some feathers in the air and nothing remotely looking like a system in place.

There are people in these meetings who squawk because all the other chickens are making noise, there are people who add redundant checks and measures and steps because they realise their own make-work may be reduced, and there are people who really shouldn’t be allowed to add their tortuous mental loops into the process.

You know you’re in the presence of the latter when the subject of outcomes comes up on the agenda. These people want to track and report on everything it seems. Mistaking visibility for control, they want to see “every stationary order under £15 for the year 2001” (a genuine phrase heard in a chicken-fest). What then unfolds is a system where a huge amount of ROD – my own coining for wRite Only Data – is captured. Every user, at every point in the process is suddenly burdened with entering data they may barely understand (or indeed know) into the system – resulting in a massively bloated interface that nobody wants to use. Quite simply, the clichéd ROD for your back.

Don’t get me wrong, I have some good clients relationships; many lasting over years where such happenings don’t take place, where the chickens are carefully cooped before a requirement meeting even takes place. One has even got themselves to the point where they are able to judge how long it’s going to take me to deliver their requirement – and how I love them and cherish them as a client, and how much more willing to stretch things we are when things go to the edge of the specification.

A waterfall is an elegant system for getting water downhill.

These people capture only the data they need, only generate the documents they need and only capture the data they need – and they can take advice about how best to organise these into an overall business solution. People who are of genuine value to their business are never worried about “systems” taking over their part in the organisation, they instead relish the chance to get away from the make-work and get on with their job – making the business better, and not carefully crossing off items on a printed report with a biro and a rule. This latter of course would be a firing offence in my own business!