July 20th, 2010 by adam

Someone makes a highly controversial amateur YouTube video, showing an Auschwitz survivor and his children and grandchildren dancing at Auschwitz, to the song “I Will Survive”.

And, in the middle of the debate *that* stirs up, someone hits them with a copyright violation, forcing YouTube to remove the video. There’s no option to read why – although my best guess is that they “didn’t pay to license the music”. Ha! Can lawyers silence debate where the Third Reich failed?

There’s no link to who ARPA actually is, although it seems to be an Australian music-copyright org that specialises in “collecting money”.

I think this situation neatly sums up quite how much loathing I have for some of the selfish, greedy, petty-minded scum that fight for the preservation *and infinite extension* of Copyright law, and who seek to criminalise everyone in the world who won’t feed them money.

(and, incidentally, if this *is* over money – I’m surprised the challenge went ahead, given that Copyright law has specific terms exempting “commentary” (i.e. exactly this kind of situation). Actually, I’m not. It’s the kind of thing you expect of the “guilty-until-you-bribe-a-lawyer-to-prove-you-innocent” laws that the USA (especially) has put in place in recent years (and other govts to a lesser extent))

July 19th, 2010 by adam

Is there a place to complain that UK government departments are breaking the internet standards and refuse to fix their websites?

Occasionally, you find sites that do this. Usually, when you tell the organization, they’re a little embarassed, and rush to fix them.

From HMRC, I got a polite, pedantic, *but entirely incorrect* response telling me that the “standard” was X, when I know that to be false (as does anyone who has read the offiicial standards, as documented by the Internet RFCs).

They apparently can’t be bothered to read the standards, and don’t care that they’re wrong.

No wonder so many people hate civil servants: holier-than-thou attitude coupled with being clearly, inarguably, wrong. Sigh.

July 18th, 2010 by adam

Android 2.2 has a nasty bug where it disables the SD Card on Google Nexus One phones.

Fine, I found a workaround. But there’s a down-side – what happens when you only AFTERWARDS remember that it’s got the ONLY copy of several hundred photos, including plenty of uniques that can never be re-captured?

No way I was getting the photos back – after all, it *formatted* the card.

But … saved by Google’s poor OS … a couple of days after I’d formatted the card, I had the thought:

Hmm. This Android OS has a lot of design flaws and bugs. I wonder if … “formatting” the SD card doesn’t actually format it, but simply marks all the files as deleted?

After all, it’s flash memory – older Flash cards could only be formatted a set number of times before they’d stop working. Maybe, just maybe, Google’s OS doesn’t do what it says it does…

Yep, turns out that’s what it did: mark all the files as deleted, without actually deleting them. So I was able to get back about 95% of my photos. I could probably have got all of them if I’d known in advance that the format … doesn’t format.

Time for … CardRecovery

http://www.cardrecovery.com/

Card Recovery is awesome. It’s an excellent example of one of the best sales techniques:

  1. Free (no barrier to trying it)
  2. Very easy to use (idiot-proof)
  3. Shows you exactly what you’ll get for your money (it does all the work FIRST, and shows you the photos it’s recovered – all of them!)
  4. Offers a one-click, in-app purchase of the “full” app, that will actually *save* all those photos it’s recovered
  5. Reasonably priced

I got to the end, and was expecting something vicious – $500-$1000 price (after all, they have you in a vice at this point). Their software proved it was possible – the data was still there – so I prepared myself to manually recover the files, even if it took many hours. I’ve been using computers so long that I’ve had to do data-recovery by hand more than once, in the days before data-recovery firms existed.

Most “data-recovery” firms do this: get the customer in, get the physical media off them, show a tiny piece of data to give the customer hope (oftenn deliberately NOT mentioning how much data is missing), then charge outrageously high prices for their services, because at this point it’s hard for the customer to back out of the deal.

CardRecovery was barely $50.

No hesitation, I bought it on the spot. Especially since I’ve now got this handy utility should I ever need it again in the future…

July 15th, 2010 by adam

Google’s Nexus One auto-upgraded a few weeks ago, to Android 2.2

It immediately broke itself. It was no longer able to use the SD card.

As a side-effect, it was impossible to install any applications. Making this a very expensive, very heavy, very slow excuse for a mobile phone.

The error was that the SD card permanently unmounted itself, with a message in status bar “SD card can now be safely removed”, accompanied by an error if you tried to install anything: “your SD card is unavailable or missing” (or words to that effect.

Factory-reset of the phone? Still broken.

By fiddling around, I eventually found the solution (and you’re probably not going to like this): Format the SD card.

Yep. It seems that Google changed something between Android 2.1 and 2.2 that – in some cases – makes it unable to read the SD card any more.

For the record, other things I tried include: remove the card physically and reseat; dismiss the error messages and try again; install apps from private sources (e.g. our own apps we wrote).

July 14th, 2010 by adam

There’s a conference in Brighton this week, and one of the industry media – GamesIndustry.biz – has a base here, so they’ve been cropping up a lot in the reporting. In passing, I noticed some glaring howlers in their web-design. The 1990’s called, they want their web-design templates back…

Three glaring errors I noticed in particular. One of these they’re in good company – it’s the same thing Rupert Murdoch has done, along with sticking his fingers in his ears and screaming “NA, NA! I CAN’T HEAR YOU! GO AWAY AND TAKE YOUR STUPID INTERNET-THINGY WITH YOU, YOU FREELOADING BASTARDS!” (not a literal quote, of course). Although a lot of people seem to think that’s a weak strategy even for the mighty news empire…

1. Sell a large number of Flash ads, and put them ALL in the same place. At the same time

What do you see when you view a page on this site?

If you have a laptop, and you surf their site, does the battery last noticeably less than normal? (hint: yes, it should – I’ve seen this happen on a wide variety of PC and Mac laptops)

Why?

Because they put not 1, not 2, not even 5 … not even TEN … but up to FIFTEEN SEPARATE FLASH ADS all animated SIMULTANEOUSLY on every page.

Flash wasn’t designed for this – the flash runtime can overhwelm a modern computer with just 1 rogue flash app; 15 is begging for trouble.

I suspect (because some of my former employers used to purchase them, regularly) that these “mini-ads” are a decent source of revenue for GI.biz. It’s a pity then that they’re mostly Flash, because that means an awful lot of people in the target audience (game developers), see something like this:

Screen shot 2010-07-14 at 20.09.40

Incidentally, I offer a tip-of-the-hat to Relentless, whose animated-GIF has so many frames of animation that it smoothly animates some stuff that looks straight out of a Flash ad. Smart move on their behalf – they DIDN’T use a Flash movie.

OMGWTFBBQ! That must take TONNES of animating frames! Why, yes – it uses an *unholy* 50 kilobytes, just to display one ickle GIF. Shocking. And yet … in 2010 … such a tiny tiny file in the scheme of things that it suffers nothing for not being Flash. (Flash was originally needed because internet bandwidth was poor; it only gradually grew into the all-singing, all-dancing beast we love today)

2. Hide all your content. Keep your news … secret

Try viewing any article on the site.

Follow any link that a friend sends you via email

Click on a link in any blog post or forum post.

Actually … you’ll have some trouble there. Lots of blogs and forums no longer link to GI.biz. Why?

Because anyone who follows the link only gets to see ONE SENTENCE of the article:

Screen shot 2010-07-14 at 20.19.36

Hmm.

3. Block anyone who uses Gmail

If you try to sign-up on their site for an account using Gmail, the site refuses to “allow” you to create an account. It seems they have hard-coded a list of email domains that they consider “unacceptable” for game-developers to use.

Funny. I’ve been using gmail for my professional email for many years now. It seems a fairly common practice. Google’s … well … Google is a pretty well-known company these days. Their products are … well … kind-of popular. No?

I tried emailing the site admins to ask if there was a way I could create my account anyway – it’s fairly easy to check that my gmail account is bona fide. A funny thing happened.

Their website has no email addresses. Instead, it has a javascript that creates email-addresses on the fly. It’s a neat little javascript, and used differently would be pretty cool. But the way they chose to use it has two obvious effects:

  1. It is impossible to use a web-mail client to email anyone at GamesIndustry.biz direct from the site (the right-click, “copy email address” won’t work because of the javascript)
  2. Spammers have to look at the source-code to find the email address, and be a very very little creative with their bots (well within their capabilities these days)

Internet: 0, Newspaper/Web newsite: 1

O RLLY?

No, not really. I’ve got nothing against the news-site, and I’m well aware that this is only an echo of a bigger, louder noise: mainstream newspapers are in their dieing throes, lashing out at anyone and everyone in their panic.

But I’m suprised that a tech-industry focussed site chooses to fight so hard against the medium that so much of its own industry relies upon and worships. The first and third items above I would normally attribute to ignorance and just spending too little money for their web design team. But the middle one reflects an active decision to block the internet at large – even though the workaround is to create a “free” account, it’s an artificial barrier entirely of their own making.

I’ve spent a lot of time this year working with or around mainstream journalists, magazine staff, and authors. I’ve noticed a lot of this stuff going on. This is just a personal opinion, but … I humbly suggest that whenever ANY news/journalism site acts as though it’s at war with the very medium that the world + dog uses for spreading said news … that whatever else happens, it’s probably not going to end well.

July 8th, 2010 by adam

…and Amazon’s intelligent recommendation engine leaps into action:

(if you don’t know who Tim Langdell is, and you work in the games industry, just Google him.

July 6th, 2010 by adam

There are many examples, every day, of people saying stupid things on the internet. But rarely do you see smart people write long reasoned arguments that they appear to wholeheartedly believe, yet are fundamentally untrue.

Jason Robert Brown has written a great post, and comes across as highly literate, reasonable, fair, etc. I was rooting for him from the start. Sounds like a nice guy.

But it’s long. So … it’s quite far down that you get to the tiny tiny key step in the exchange. This is the point where the author’s whole argument – a beautifully written argument – crumbles to dust:

“And I say to you that just because technology makes doing a bad thing easier doesn’t mean it’s suddenly not a bad thing.”

Funny. They said that of the Printing Press too. This is precisely what technology DOES do: it changes us. It changes society. Nothing is sacrosanct; our definitions of “good” and “bad” fluctuate. Not even the law is static. Ask any senior lawyer – the law is a fluid concept, defined by the society of its day.

There’s a fascinating exercise: to examine a period and place in history simply by looking at the prevailing laws of the day…

IMHO … at his core, Jason is in that group of people that still haven’t come to terms with the unavoidable side-effects of the “copy” button that exists on all digital-data devices. This is a storm that brewed for decades, and burst with music piracy. Everyone *ought* to be aware of it by now, even if in practice a lot of old-guard media and authors seem to be jamming their fingers in their ears and screaming “I CANT HEAR YOU! GO AWAY!”.

How much longer before posts such as his cease to become anything more than “fascinating historical record … of a time now passed”? Not much, I think…

(PS: I’m ignoring the very much NOT smart – and rather offensive – attempts to re-define words such as “theft” in support of a specious argument. I believe the author did that purely accidentally)

July 5th, 2010 by adam

(where normaly people might “Be original, then Apologize if you fail”)

Just a minor piece of recent DRAMA! DRAMA!, something to cheer up the week…

This excellent piece of Advertising / Fun / Augmented Reality / Creativity was – like most big-budget ideas – based on someone else’s idea, someone who had the basic idea (and proved it non-commercially) first.

So far, so good.

This is the 21st Century. People notice when you clone ideas, and they comment. A lot of comments are brief and reflect the emotional reaction rather than a considered opinion. Especially if you disingenuously claim to have invented the idea, and put out press releases to that effect … when there’s plenty of evidence suggesting otherwise.

Still, that’s how life goes; you try something, you veer too close to “copying”, and you get some minor pillorying on a public website. You re-adjust; next time, you’ll try to add a bit more novel to an idea – or you’ll work harder to give credit where it’s due.

OR … or, one of your team can always just go for the all-out nuclear option, and insult everyone and everything in sight. In the world-readable comments thread. For bonus points, you can then delete your comments a day later when you realise what a douchebag you appear, and how damaging it’s become to your future career:

http://www.flickr.com/photos/pixelsumo/4752204508/sizes/o/

(I love how Nicholaus is naive enough / bad enough at his own career to imagine that simply deleting or editing a comment makes all evidence of it vanish :))

June 25th, 2010 by adam

This post shows how to fix one of the biggest time-wasting aspects of Xcode: the default project. Every time you start writing a new app, you first typically waste 15-30 minutes “un-****ing” Apple’s defaults. The defaults are terrible.

e.g. they are effectively unusable with Apple’s own SVN integration (Apple clearly doesn’t use SVN internally), unless you are the only person working on your project (”no teams allowed”). But the good news is … most of this can be fixed!
(more…)

June 15th, 2010 by adam

If your startup sells stuff via the internet (you have an online product, service, web-app, etc), this may be the single most important thing to get right (assuming your core idea, team, etc has inherent merit). And yet so many companies spend so much money doing it so wrong.

Why are modern software companies so bad at selling software? Today I was looking at Scrum tools (or Agile if you prefer), and I was struck by how hopeless some of their websites are. With some of these sites, I am sure that I could increase the sales of most of these companies by hundreds or thousands a year, just through basic principles of sales.

(and, obviously, HOWEVER you design your sales page, you should be using A/B testing to increase sales, conversion, etc. But A/B testing is no panacea: you still need the creativity and understanding to make the “big leaps” yourself)

Example: VersionOne

I’m going to pull out one example (by accident, the first I came across). Many others are much the same.
VersionOne.com

Before we go further, let me be clear what “kind” of customer I am. I’m currently looking for solutions for two commercial setups. One is for tiny projects on a case-by-case basis. This would be 5-seat licenses (worth up to $3000 at VersionOne’s current prices). The other is for a company-wide purchase of up to 30 licenses per annum (worth up to $15,000).

But, at the same time, my last full time job was running development for a large development studio. I was the primary reviewer and purchase-maker for software tools that were 50-person per annum immediately, and meant a commitment of up to 150 within 3 years. I’ve done a *lot* of this purchase-review process, on a lot of software.

My negative reactions to VersionOne’s sales are fairly consistent across the 3 profiles (although the reasons behind that are complex)

Landing page, from Google: the “don’t ask questions, you’re too stupid, just buy instead”, and “we love ourselves, we’re awesome” page

Page: http://pm.versionone.com/Trial_ScrumProjects.html?c-aws=trs&gr-tss&v-029abt&gclid=CNGTgsrEoaICFUcA4wod82WOwg

This has a *concealed* URL, so it pretends to be the front page, but actually lies, and redirects you to this page instead:

Ont this page, your website states it’s a commercial product, yet REFUSES to answer the single most important question: how much does this cost?

There aren’t even any LINKS to finding out about the product. It’s just “buy our product, or piss off”.

This page serves one purpose: lock the customer into a product they don’t want. You are “not allowed” to know the cost, you are only “allowed” to “signup now for a 30-day trial” – you have to commit yourself, and they’ll sting you with a price later, when you have no choice.

Word of advice: merely making something “free, for a few minutes, then I charge you” does NOT lower the customer’s barriers to purchase. For an ultra-long-term product like Project Management tools, it often has the *reverse* effect. The MINIMUM trial for a PM tool is “one project”. Most projects – using new tools – will need several months; 2 week to learn the tool, 10 weeks to run + launch + finish the project. The customer knows this; they know that a “30 day trial” is completely dishonest.

So, we use the navbar, and head to the “Product” page:

Product page: the “Want more info? Oh no you don’t! You’re too stupid, you’re just a customer!”

Page: http://www.versionone.com/Product/

I’ll sum up the stupidity and smug self-satisfied attitude of the person who wrote this page with just one quote, their final bullet point in the top-section:

“Accelerate agile adoption”

[hey! Look at that! I'm so clever - three words all beginning with "a"! They're guaranteed to buy now! I'm so sharp, sometimes I cut myself]

Sigh. Ignoring the “infographic” which has been screen-captured with a font-size of 2pts (i.e. literally physically impossible to read), we try to do something useful with this page: review the product (we’ve given up on pricing, for now – they obviously don’t wany anyone to buy the product, but maybe the product is so good we can force our way past that?)

Product page, part 2: the “we don’t trust you, we’ll spam you with marketing crap”

Page: http://www.versionone.com/Product/

(below the infographic)

Just look at that page. It has literally zero information about the product, yet it’s the “product” page.

Instead, it has paragraphs of marketing crap. There’s no other term for it; let’s look at the first example.

Bullet-point: “Product Planning”

What does this mean? Absolutely nothing. BY DEFINITION, this is a whole website devoted to project-management-planning software used on projects that create products. Why do you repeat this, in such a childish gross genealization, as if it’s a “feature”?

Ah, but … actually, that’s not necessarily true. Scrum is often used on projects that are NOT generating a Product.

So, in fact, this lazy marketing title has already told some of the target-customers: “Don’t use our product. Go away”.

Let’s look at the text underneath the bullet:

“Plan and manage your requirements, epics, stories, and goals across multiple projects, products and teams.”

What is this – Dictionary.com? Why are you patronising me by telling me what you think “Product Planning” means, as an abstract concept? What kind of project manager – or engineer – is so stupid as to not know what it is they do on a day to day basis, and to feel happy that you’re telling them?

I WANT TO BUY YOUR SOFTWARE, NOT LISTEN TO YOUR PHILOSOPHICAL DISCOURSE.

I suspect that the weak marketing person who wrote this copy thought it “looked nicer” to put features into a long sentence. Let’s look at that sentence, from a copy-writing perspective. It has eight separate phrases. EIGHT. The average sentence has 2-4. Concise sentences have 1-2. Waffle has 5 or more. This is a sales page; every sentence should be no more than 3 phrases. EIGHT! NO-ONE is going to pull useful information from that sentence.

Onto another problem with this page, for the customer who comes here: No screenshots. Anywhere.

OK. Take a deep breath. This is a company that, so far:
– wants to deceive us into locking-in to their product
– patronises us intensely
– works hard to hide features (check that “unreadable” infographic)

…but let’s put all that to one side, and drill down into the links from the Product page.

Features (1 of 8): “You can look, but don’t touch AND DON’T LOOK CLOSELY!”

Page: http://www.versionone.com/Product/Product_Planning.asp

Finally, if you follow one of the links from this page, you get to a page that contains some actual, concrete, info about the product. There’s even some screenshots!

Oh. BUT. You are “not allowed” to actually see the screenshots. They’ve been deliberately blurred-out a low-resolution, so that text is literally unreadable and there is NO WAY to judge the product. (NB: this is *after* you’ve clicked on the almost-full-size thumbnails in the page). They are then further blurred (to no purpose except to fit the Web Designer’s fetish for popup images) and embedded in the page.

Overall impression: this company knows it’s own product is not fit for purpose, and will do anything to stop the customer from finding that out until AFTER they’ve paid their money. Whatever you do DO NOT BUY VersionOne’s project-management software.

Final thoughts: First one is free

A decent usability person – or a really good web designer – would make huge sweeping changes to that site.

A flippant starter, something I’d personally try immediately (today): move the “see it; drive it; try it” buttons that hide in top-right of the site to CENTER STAGE, both on the Product page and the Google Landing page.

AND … I’d add a fourth button: “Buy it”.

What? There’s no “buy” link on this site? Yep. I think that eloquently sums up what a poor job this site does of MAKING MONEY FOR THE COMPANY.

(NB: and I *absolutely* would instigate A/B tests to prove – day by day, hour by hour – that my changes were having a noticeable effect on increasing sales to the site. If you don’t do that, then you’re just pissing into the wind. You have no idea, afterwards, whether your changes “worked”. See Sergio Zyman’s book for more…)

Where do these terrible sites come from?

I believe that these often-amateurish websites come from one of two sources (possibly both):

1. Expensive “Web Design” agency that only cared about making it “beautiful” without understanding a single thing about the reality of sales. In the example I run through below, dead giveaways include: Popup images that are only 15% larger than the thumbnails that trigger them; grey-on-white text; very small font-sizes. All those are characteristic of visual designers who know nothing about product sales.

2. A marketing team that’s worked for big corporates (multinational, public companies) and thinks that the most important thing in their job is to “clone” the website of “a real company – you know, like Microsoft”, and pretend to “be like the big boys”. They have no idea why those websites look the way they do, and don’t bother to ask themselves; they just blindly clone it. In the example below, dead giveaways include: 12 pages to describe a simple product where 3 would have been more than sufficient; hiding information at all costs; never committing to a list of features; using “freeform text” instead of simple “bullet points” to describe the product.

June 13th, 2010 by adam

From one of those strange wending web-browsing sessions that started as innocent “work-related research” and ended up following the history of CDC…

IBM, 1964:

How is it that this tiny company of 34 people —including the janitor — can be beating us when we have thousands of people?

…to which Cray reportedly quipped:

You just answered your own question.

(and, incidentally, FUD – a phrase I associated with the 1990’s and linux – apparently dates back to the early 20th century. It puts in an appearance here, in the 1960’s, and lead to CDC winning a lawsuit for $600 million. Nice. Can you imagine someone pulling that one off against Microsoft in the 1995-2005 era? Or Apple, today? I doubt it…)

June 11th, 2010 by adam

Some people are telling me I should just let it go, but honestly I just can’t do that. I’d rather quit.

(As they say: It’s funny, becaus it’s true. If you develop for Apple platforms, that eloquently sums up how Apple (currently) appears to everyone they partner with: a childish, passive-aggressive approach to everything)

June 7th, 2010 by adam

Apple added some of the earliest, best *hardware* support for mouse and trackpad gestures (2-finger swipes, pinch/zoom, etc), but has been very slow to add support for gestures to their *software*. Out of the box, OS X can do almost nothing with them. Previously, I’d used the quick-n-dirty-but-it-works “MultiClutch” app to make OS X much more usable.

But I broke my laptop, bought a new desktop, and had to re-install everything. Today, I found this awesome app:

http://blog.boastr.net/?page_id=1619

Why’s it so awesome? Well, plug in an apple mighty mouse, hit “Show Live View” and start touching your mouse. You can visually track all 4 touch points, and try out a variety of funky custom gestures.

NB: this isn’t old-fashioned “move the mouse in circles” gestures. Oh no. This is the new-style “glide your fingers over the surface of the mouse” gestures (treat the top of your mouse like an iPhone).

Great little app. Even has a decent UI, and options for exporting/importing settings, so you can setup some very complex setups on a per-app basis, share them with colleagues, etc.

May 26th, 2010 by adam

(Google just made a major change to Gmail accounts in the UK, now that they’ve settled a trademark case brought against them. This is great – it will simplify mailing list management for a lot of people, and everyone in the world can (legally) be “@gmail.com”)

However … I’ve now had two friends write the above (”it said I didn’t have to do anything”) when asking for help with the changeover. Hmm. When the message came up for me first time, I got that impression too, but looking at it more closely, it doesn’t explicitly say that:

gmail changeover screenshot instructions

Anway, two friends in quick succession is a suggestion that I’m going to have to answer this question a few times. Instead, from now on I’ll just send them a link to this blog post :). Copy/paste of my original response:

Sorry, Google’s instructions aren’t very clear. You need to click the “more info/FAQ” link to get the “true” instructions, which include this gem:

“Mailing Lists: If you have signed up to send mail to mailing lists on behalf of your @googlemail.com address, you might need to re-register for the group using your @gmail.com address. Google Groups will automatically accept your new address.”

…although Google is being disingenuous when they say “might need to” – they know that *most* mailing lists will require you to manually change address, re-signup, or ask the admins to change your address :).

I like the visual approach that Google took here – the page is simple, clearly formatted, etc – but it’s tragic that it fails to include the critical information. “Breaking every mailing list you are on” should not be relegated to “Have questions? Not sure you want to switch?” – it should be right there on the main screen with a big red warning sign. I’m intrigued as to how the page was designed: it’s hard to believe that the usability people missed something as obvious as this. Are mailing lists not used that much by Gmail users? Even harder to believe. Have mailing lists fixed the gmail/googlemail problem? Possibly, but none of the ones I administer have (mostly for orgs that are using mainstream “free” list managers).

May 25th, 2010 by adam

Here we have Zynga recruiting for a CTO in SF:

(see also the last post, on UK online games jobs)

May 16th, 2010 by adam

UPDATE: I’ll add other roles in as/when I get the OK from the relevant people; not all of these are public yet.

Despite the heavy rash of studio closures (well documented by Nicholas Lovell), it seems there’s a lot of exciting online/social games hiring going on right now – I’m getting lots of requests from friends, ex-colleagues etc.

  • Head of Mini Games at Mind Candy (London-based social games startup; runs a successful kids MMO – Moshi Monsters)
  • Financial Manager / Social Gaming Economy Modeller and Virtual Goods Data Analysis at Lockwood (Nottingham-based online / virtual world startup; built most of the cool stuff in PlayStation Home, now building their own MMOs) – *entry level

There’s also some interesting roles in publishing, and some in startup online games companies.

If you’re UK-based, you’ve worked in MMO / social games / etc, and you’re looking for a job, feel free to email me. No CV’s, just tell me who you are and what you’re looking for in 4 sentences or less.

Or, if you see an entry-level job here you want to apply for, ditto and I’ll put you in touch (or just follow the links to the company directly).

May 11th, 2010 by adam

Dear Eric … here’s my problem:

Somehow that didn’t feel right for Google. We wanted something much more transparent and open” (Eric Schmidt, Chairman/CEO Google, writing in the Harvard Business Review this month)

How, exactly, would you reconcile that with the fact that I had to serve Google with a legal document (here’s how to use the Data Protection Act of 1998) to get the feedback that your employees admitted they already had?

How do you explain the difference between the 10 seconds of feedback I received from your in-house recruiter, and the 12 pages (yes, *pages*) of feedback I received after I served the legal notice. Is this transparent? Is it open?

I’ve met many Googlers, and a lot of them are excellent salespeople for the company. If I truly believed that Google lived up to it’s claimed principles, I would go to great lengths to work there. Why devote my time, the precious days of finite life, to any other kind of organization? Before the interview process, I *did* believe, thanks to the testimonies of friends and ex-colleagues.

But the reality is clearly – “transparently”, to use your terminology – different. And it’s only thanks to the insightful and diligent work of UK lawmakers that I got anything out of Google at all. Amusingly, you didn’t even pay my travel expenses! Ironically, at the same office, when I went to the London Open House party, many years ago, I provided less … and received more … than when *you* asked *me* to come to an interview for a job. Surely that’s the wrong way around?

(I’ve still got my Google Open House t-shirt, and I got free food and drinks at the event. Thanks! That’s more than I got from the interviews…)

Personally, I have huge respect for people. I believe it’s the most important thing *for me* in any business. There are industries where individuals don’t really matter – I actively choose not to work in those industries. As experienced first-hand, my values wouldn’t allow me to work at a corporation like Google.

Why is it acceptable to those of you who work there now?

Footnote…

So, Google doesn’t live up to the hype? Shrug. My reaction: I’m building my own company that does. I’m not going to sit around waiting for someone else to make it for me.

Also … about that 12 pages of feedback… I checked with Google whether they’re OK with me publishing it (me, I really do strive for transparency ;)) – they said something very close to “it’s your data – do you what you want”. I’ve already sent it to a wide array of friends and ex-colleagues – people who know me well enough, both good and bad, to read between the lines and second-guess the context.

But it’s hugely context-dependent (i.e. you had to have been there to understand what’s going on), and there’s some extreme statements in there. It would be very easy to misinterpret, sometimes making Google look much worse than it should, sometimes making me look much worse than it should. I’m conflicted on how to publish it; transparency is great, but … you have to consider your personal responsibility too.

May 11th, 2010 by adam

Beautiful, and disturbingly accurate.

May 9th, 2010 by adam

I’ve been writing about Entity Systems sporadically for the last few years. Recently, I finally had the time and the excuse to build one of my own (i.e. not owned by an employer). If you haven’t read the main series of ES posts, you should do that first. There are many things in the world masquerading under the Entity/Component banner – and even more that just coincidentally share the name, but describe something else completely. It’s worth understanding which variant I’m talking about before you read about what I’ve done :).

Why build an Entity System?

At a generic level, this is covered in the other posts. But it’s taken years for me to have the time/inclination to write a new one from scratch outside of my day-job. What happened?

  1. I left my iPhone in America, and it took 2 months to get it back
  2. Google gave me a free Nexus One, in the hope I’d write something for it (ha! Their cunning plan worked…)
  3. The Android marketplace is such a miserable morasss of third-rate crap that eventually I was compelled to write my own Android game … just so that I would have something to play (there are very few games on the Android store that are even worth the time it takes to download them)

I’ve been making games for a long time. I know how much effort will go into it, how much time, and how much slog there is before it becomes worth it. Writing a game on your own often means putting in 90% of the effort to get 10% of the reward.

Enter … the Entity System. If I were to pick a game-design that mostly used data-driven game features, I could implement it around an ES, and massively reduce the amount of planning needed to get the game running. I could maybe have a working game after a mere 20% of the effort. Hmm…

Building the ES for Android

Android runs something that’s *almost* Java (although more on that later – Android’s version of Java is very slow at some of the core libraries, and it really shouldn’t be). Technically, Android supports all the core data structures from Java (Collections), and the templating system (Generics).

If I were writing an ES in C++, I’d do it using templates without pausing to think; I wondered how well the same might work with Generics, given that Generics is *not* a complete templating system, although it provides quite a lot.

Getting started: early ES decisions

How to design/implement this thing? Well, we know one thing for sure:

Entities have a single name/label/global-ID. Entities MUST NOT contain ANY DATA: these are NOT objects, this is NOT OOP!

There you go, the Entity class wrote itself:

public class Entity
{
   public int id;
}

This immediately raised some concerns for me, being the seasoned coder I am (ha!). How the heck was I going to write any code that dealt with these things if I didn’t have references to them? Obviously, sometimes you do have references, but other times you expect to follow refs from within the objects you have, to get to the objects you need. That wouldn’t be happening here, since there are no inter-object refs.

public class BaseEntitySystem implements EntitySystem { /** I'm too lazy to write a "safe" method to get a globally-unique ID; for now, I just return 1 the first time I'm called, 2 the second time, etc... */ protected int getNextAvailableID(); /** Whenever you create an entity, you'd better invoke this method too! */ public void registerEntity( Entity e ); /** The method to solve my fears above */ public Entity getEntity( int id ) /** * Merely removes the entity from the store. It becomes a GC candidate * almost immediately (since all other refs are transient) */ public void killEntity( Entity e ) }

…but, again, being a Veteran coder, the survivor of many painful battles on the field of programming … I didn’t trust myself in the slightest to “always remember” to invoke registerEntity. Quick trick: give the Entity class a static reference to a default EntitySystem, and have each EntitySystem check if that reference is null when starting; if so, set itself as the “default”.

public class Entity { ... public static EntitySystem defaultEntitySystem; ... public Entity( int i ) { id = i; if( defaultEntitySystem == null ) throw new IllegalArgumentException( "There is no global EntitySystem; create a new EntitySystem before creating Entity's" ); defaultEntitySystem.registerEntity( this ); } ... } public class BaseEntitySystem implements EntitySystem { ... public BaseEntitySystem() { if( Entity.defaultEntitySystem == null ) { slog( "Setting myself as default entity system (Entity.default... is currently null); self = " + this ); Entity.defaultEntitySystem = this; } } ... }

W00t! I can create Entity’s, and I can find them later on. Awesome. What about those Components, then?

Getting started: Components in Java

I’ve done ES in C++ before, with real templates, so I wasn’t really thinking at this point … I just ran with what seemed natural based on prior experience. The thought process (had there been one) would have been something like this:

  1. This is java, I use Eclipse: I absolutely *must* have the IDE know what data/fields exist in each component so that Content-Assist/Autocomplete works 100%. Otherwise I will gouge my own eyes out having to remember, and doubly so each time the app compiles but dies at runtime because of a typo in a field-name.
    • Requirement: each unique Component must be defined as a java Class, with each of the fields being a public member of that class
    • Requirement: to access a Component of a given Entity, you must invoke a method which returns something that is typed (as in language typing) to the correct Class

I made a Component class, and had all Components extend it; there is a particular reason for this, but it doesn’t matter right now – essentially, it lets you define shared behaviour for all Component subclasses, and just saves you time on typing.

My first real Component:

(NB: I defined this *inside* another class, because I couldn’t be bothered having N source files for the (large number of) N Components I was bound to create. Hence the “static”):

public class MyEntitySystemExperiment { ... static class Position extends Component { float x, y; int width, height; float rotationDegrees; @Override public String toString() { return "("+super.toString()+" @ ("+x+","+y+") * rot."+rotationDegrees+")"; } } ... }

Great. I have a component. Now comes the largest single piece of work in the entire implementation of the ES: writing the methods to:

  1. Add a component to an Entity
  2. Fetch a component from an Entity
  3. Remove a component from an Entity

Fetching a Component from an Entity

This is the win/lose point: if this works well, our ES will be nice and easy to use. The other two methods (add and remove) are simply twiddling bits of data. This one is the challenge: can you make it *easy* to write code that uses the ES, and for that code to be clearly *understandable*?

public class EntitySystemSimple extends BaseEntitySystem { HashMap<Class, HashMap<Entity, ? extends Component>> componentStores; public <T> T getComponent( Entity e, Class<T> exampleClass ) { HashMap<Entity, ? extends Component> store = componentStores.get( exampleClass ); T result = (T) store.get( e ); if( result == null ) throw new IllegalArgumentException( "GET FAIL: "+e+" does not possess Component of class\n missing: "+exampleClass ); return result; } ... }

Boom! It works.

Let’s just stop briefly and I’ll explain why. Reading Java generics code from cold (just like reading C++ templates) often takes a lot of hard thinking.

Looking at the “result” of this method, we want it to be (enforced by the compiler):

  1. “an instance of a class that extends Component”
  2. “an instance of the particular class/Component that we requested – not just any old subclass”
public <T> T getComponent( Entity e, Class<T> exampleClass )

Here, I failed. I wanted the signature to be:

public <T extends Component> T getComponent( Entity e, Class<T extends Component> exampleClass )

…but I couldn’t quite get it to work. I’m too rusty with Java Generics (hopefully someone else can point out my stupid mistake(s)).

But for the most part, it works. Because it causes you to write application code that looks something like this:

public void doSomethingWithAnEntity( int globalId ) { // remember, we NEVER hold refs to Entity objects for long Entity e = entitySystem.get( globalId ); Position position = entitySystem.getComponent( e, Position.class ); position.x = 5; }

…and what’s far more important is that the “type” of the “Position position = …” line is already hard-typed to “Position”. So, the content-assist will *auto-complete* anything put after a dot on the end of that line, e.g.:

entitySystem.getComponent( e, Position.class ).AUTO_COMPLETE

…so you can instead write your method much quicker, and yet very clearly, as:

public void doSomethingWithAnEntity( int globalId ) { // remember, we NEVER hold refs to Entity objects for long Entity e = entitySystem.get( globalId ); entitySystem.getComponent( e, Position.class ).x = 5; entitySystem.getComponent( e, Damage.class ).hitpoints = 145; entitySystem.getComponent( e, Renderable.class ).foregroundColour = Color.red; }

Time-out: HashMap

HashMap is the “correct” class to use in Java for this setup: it’s the exact equivalent of Hashtable / Dictionary / etc in other languages. We need to map (somewhere, somehow) from one thing (an entity) to another thing (a component).

NB: this does not mean that you have to use HashMap as your data-store for the ES; I positively encourage you to consider other options. I used it here as the most obvious, simplest possible structure that would do the job. If you think back to my posts on Entity Systems for MMO development, I’ve often suggested that the data store could *and should* be any of many different things. In particular, SQL databases make for an excellent data-store (and remember you can get in-memory SQL implementations that do away with all the expensive write-to-disk stuff).

Unfortunately … Android seems to only partially support HashMap. You can use the class, but it runs an order of magnitude slower than you expect for a normal JVM (compared to the speed with which it runs other methods). It seems to have problems with the hashcode methods, but also even with basic iteration over the Map contents. Odd. Later on, I had to do some tricks to speed up the ES, just because of this problem.

Fetching a Component from an Entity: Redux

The examples I gave above for accessing components were lean and clear on the right hand side (thanks to autocomplete and strong typing), but terrible on the left-hand-side. By the magic of OOP, I’m going to clean up the LHS. BUT (and this is a big “but”) … make sure you fully understand what I’m doing here. With what I’m about to do, it would be very easy to fall into one of the traps of ES development: slipping back into OOP techniques.

Looking at the example:

entitySystem.getComponent( e, Position.class ).x = 5; entitySystem.getComponent( e, Damage.class ).hitpoints = 145; entitySystem.getComponent( e, Renderable.class ).foregroundColour = Color.red;

… applying OOP mindset, we see that the first argument is redundant; the Entity already knows about the EntitySystem to which it’s registered.

Also, we know that the Entity class will never have any methods or data other than the ID. If that’s the case, the only thing we’d ever “get” from an Entity is a Component. So, we can add this to Entity:

public class Entity { ... /** Gets a filtered view of the entity's data, only returning the subset that * corresponds to a particular one of its components */ public <T> T getAs( Class<T> type ) { return source.getComponent( this, type ); } ... }

…which converts our usage example to:

e.getAs( Position.class ).x = 5; e.getAs( Damage.class ).hitpoints = 145; e.getAs( Renderable.class ).foregroundColour = Color.red;

Using the ES with Systems

Recap: right now, we can:

  1. Create entities
  2. Add components to entities
  3. Read/Write the data inside each component, on a per-entity basis
  4. Fetch entities by globally unique ID

One last thing is needed before the ES can work: we need a way to fetch Entities “by component”.

e.g.:

public class MyEntitySystemExperiment { ... public void runLoop() { while( true ) { // move all the entities positionSystem.move( MOVEABLE_ENTITIES ); // check for collisions collisionDetectionSystem.process( MOVEABLE_ENTITIES ); // render all the visible entities renderingSystem.render( RENDERABLE_ENTITIES ); } } ... }

We need a way to provide the arguments that are capitalized above. We know that these should be plain-old lists of entities. We know they have to come from the EntitySystem. Finally, we know that the only defining characteristic of these lists is that everything in the list has *at least* a particular Component.

(respectively, in the example above, the lists contain: “all entities that are moveable”, “all entities that are moveable AND all entities that are barriers to movement (e.g. solid walls)”, and “all entities that should be displayed on-screen”)

So, one more method for the EntitySystem interface:

public interface EntitySystem { ... public List<Entity> getAllEntitiesPossessing( Class... requiredComponents ); ... }

“Class…” is just a convenience; in many cases, you’ll be insisting on a single Component. In many other cases, you’ll be insisting on a set of components. Java varargs provide the minor convenience of doing both of those in one method, while retaining type-safety.

The implementation of this method is obvious: it iterates over every entity that’s been registered, and checks it against ALL the required components. If it possesses all of them, it goes into the output list.

Finis

That’s it. So easy! Obviously, there’s more to it – the other methods you need to create should be mostly self-evident – but this should be enough to get you started.

Now, I’m not sure where to go from here. I’ve got a working Java ES. I’ve got some performance improvements and feature improvements. But … in practice, hardly anyone writes games in Java (except Android programmers, and there aren’t many of those), so … is it worth it?

Alternatively, I might just run through some of the practical pros and cons I encountered when actually using the ES in writing the game-logic. There’s some interesting things that came up which most people encounter sooner or later when doing their first ES, and which might be worth looking at in more detail.

One last thought…

Did it work? Did this ES allow me to write a decent Android game?

Yep. I wrote a space-invaders / bullet-hell game with it. It worked fine on Android phones for a hundred-odd enemies and bullets on screen. On Android, thanks to the crappy JVM, it started to chug after that (dropped below 30 FPS), so I had to make some substantial performance improvements, and now it’s happily rendering 300 things all flying around at 20-30 FPS. The game is far from finished, but it’s playable and fun for a minute or so – a definite achievement considering how little of it I’ve written so far.

many-entities-at-10-fps

NB: it’s got some way to go before I’ll be happy releasing it. But, given a few more spare evenings, I hope to get this up on the Android Market as a free download in the near future.

I’m pleasantly surprised that the Android phones can handle something as high-level as an ES, in a pure, unoptimized “simplest possible” implementation.

May 6th, 2010 by adam

Two more firms have proven their mettle this week (i.e.: think twice before engaging them).

As always, it’s nothing personal. If a recruitment agent is doing a job that I and others think weak, but managed to persuade an employer to pay them to do it – and to accept that standard – then all power to them; they’re just making a living. No employer is ever “required” to use an agent, and they have many to choose from; they have no excuse for not insisting on high standards. Shame on the employers for screwing-up their own employee-base like this.

See here for more examples:

  1. Lorien
  2. Aardvark Swift

Ravello/Enigma

First up, we have Ravello/Enigma, with two big faux pas.

1. You didn’t even bother to read my profile before you approached me. Hmm.

I double-checked. Yep, it’s still there, in black and white (and caps lock):

“NOTE CAREFULLY! * I only add people I actually know.”

2. You cold-contacted me with a job, and then refused to tell me what the job is. Or who it’s for. Or, in fact, *ANY REASON* I might be interested.

Recruitment Agent:
“I have the following role for you:
Job type/s: 2 roles. 6 months fixed term contract or 1 year perm.
Salary: Wide open but depends on experience really.”

Me:
“What’s the actual role? I’m guessing this is iPhone related? My standard rate for iPhone development and consulting is X”

Recruitment Agent:
“The project details are top secret as my client advised me but it is an Iphone/Ipad related role. As stated before, salary depends on experience.”

WTF? What is this – MI6? The CIA?

I tried to think of an intelligent response. I failed. Maybe I’m supposed to be “intrigued” and start begging the Agent to give me some information? “Artificial scarcity” and all that?

Frankly, I have no idea. Just too weird.

Unique Selection

Second, we have Unique Selection, asking me to do their job for them gratis (the job that they get paid to do…).

1. How many times do you have to ask me to sell-out my network to you (which – as noted above – if you bothered to read my profile you’d see I’m not going to do) .. before you get the hint?
  1. “Also, could we connect on LinkedIn?”
  2. “In the meantime if we could connect on LInkedIn that would be great”

On the third attempt I relented and pointed the agent at my profile. The one they should have read to start with.

2. Why would I do your job for you? And, even if you were paying me to find you candidates, why on earth would I not hire those people myself?

Agent:
“I wasn’t sure if you could help me but my client is looking for an perm iPhone/iPad App developer to join their team”

Me:
“I run an iPhone development team”

(basically: I couldn’t believe they were really that cheeky / dumb as to ask me to do their recruiting for them.)

Agent:
“If you were to go perm, what would roughly be the base you would look for?”

Me:
“I’m probably not interested.”

Agent:
“please feel free to pass my details to anyone you think could be interested.

Ah, yes, because those of us who actually “make things” have nothing better to do than offer ourselves up to be exploited so that recruitment agents can get a pay-cheque. Social security, eat your heart out…