August 17th, 2010 by adam

Came up recently on TCE. I finally figured out a concise definition of the job role being filled by the “good/great” Tech Directors – someone who’s worth every penny of the $150k salaries they command:

“Figure out the worst things that go wrong which nobody is specifically to blame for, and make sure they don’t happen”

The point with TD is that 9 times in 10 you have a hierachical company structure:

Owners

Company Directors

Senior Management

Exec Producer

Project Management

Leads

Teams

…with the setup that responsibility flows DOWNWARDS (companies where responsibility flows UP are very rare in games industry, IME. Nice idea but very few companies have the culture to obey that ideal!).

So … e.g. … anything that the PM’s don’t think of, and don’t delegate to one or more leads … gets completely ignored/forgotten.

This is a gross generalization – in practice, people lower down tend to notice if something’s missing, and apply pressure up the chain until someone takes it on, or take it on themselves.

That works for small stuff. But the big stuff – especially something that needs two disciplines to fix, or that is too much workload for one person to “absorb”, you need someone with management power (i.e. the authority to take people away from pre-existing tasks).

That’s where the [X] Director comes in. (X = Technical, Art, Design, etc)

TD, AD, etc have the sweeping power to get different departments to collaborate, or to persuade a Producer to relinquish some of their team for a week to get a “more important but so subtle you didn’t see it yet” problem fixed.

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.

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.

October 30th, 2009 by adam

The problem

It’s a great piece of openness to put your bug lists in the public domain. It makes it easier for your customers and partners to make decisions that save you time because they can see what’s coming and when (and save you money in reduced support requests). It saves you money in that you get free QA / testing from your users.

The downside is that it exposes to the world the places where you are especially incompetent, lazy, or just plain self-centred.

This is a recurring theme I’ve seen with corporates looking at both Open Source and also Web 2.0:

We say we’re the best, but secretly I believe we’re the worst; if we expose ourselves to the public, people will ridicule our mediocrity, and refuse to do business with us.

Also … I will probably get fired because my colleagues and my boss will finally realise what a clusterfuck I preside over on a daily basis

Eclipse, and a tale of two bugs

I was going to log two high-impact bugs that Eclipse has had for several years. Then I did a search on that area of Eclipse, and realised that the current Eclipse maintainers don’t give a **** about this whole section of the IDE – some of the core bugs we see every day were logged in 2001, and are still open:

https://bugs.eclipse.org/bugs/buglist.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&product=&content=syntax+coloring

What you find when you do some basic research

If you go looking through the bug history for some of the more “obvious” bugs there, you often find little gems of passive-aggressiveness from maintainers. That’s an exceptionally effective way of making sure people stop helping and supporting any Open-Source project…

You’ll also find endless re-logging of the same old bugs from 10 years ago, revolving around the basic problem that Eclipse lets you set everything you could possibly imagine … EXCEPT the colours that it prints text in.

(all IDEs let you set the colours; most dont give you enough control over the other parts; Eclipse fails on the basic challenge, and succeeds on the advanced challenge)

This wouldn’t be so bad, except that its default is very bright with low-contrast – i.e. very hard to read on laptops when outside, and bad to read for long periods of time. As of about 5 years ago, you are finally “allowed” to set the colours yourself – except that the app breaks if you do, because they “didn’t bother” to allow you to change the colours on 20% or so of things.

Final thoughts

The next time someone – especially at a corporate – resists openness and transparency … in any form … ask yourself this:

What have they got to hide?

Often, once you ask yourself that question of the right person at the right time, it very quickly becomes obvious what they’re hiding (if not why). A little more digging, and you can pry open the can of worms, and see what trouble they’ve been up to…

(Incidentally (and unsurprisingly), in the face of the point-blank refusal of Eclipse developers to make basic usability concessions across the board, I didn’t bother logging either of the two bugs I’d found)

October 26th, 2009 by adam

(Start by reading Entity Systems are the Future of MMOs Part 1)

It’s been a long time since my last post on this topic. Last year, I stopped working for a big MMO publisher, and since then I’ve been having fun doing MMO Consultancy (helping other teams write their games), and iPhone development (learning how to design and write great iPhone apps).

Previously, I posed some questions and said I’d answer them later:

  • how do you define the archetypes for your entities?
  • how do you instantiate multiple new entities from a single archetype?
  • how do you STORE in-memory entities so that they can be re-instantiated later on?

Let’s answer those first.
(more…)

October 25th, 2009 by adam

(because I googled it, and on the first page of hits I couldn’t find any copy/pasteable source for this common problem, here’s an answer with (poor) public domain source code)
(more…)

October 13th, 2009 by adam

I’ve now deployed iPhone static libraries in two (live) applications, and numerous updates.

This is a process that is seemingly (*) 90% undocumented by Apple, despite being (IMHO) absolutely essential for any professional iPhone developer.

[(*) - if there's docs, then I've not found it in over 6 months of googling, searching Xcode doc libraries, and asking everyone I know. I will feel stupid if it's there and I haven't found it, but I have honestly tried very hard to find it!]

I have sought help in numerous expert forums and mailing lists – and generally discovered that no-one else is quite sure how to do it either, although I’ve seen some funky ideas and methods that others have come up with.

Through trial and error I’m pretty sure I know how to do it now – but I still have no idea what the “correct” approach is – so I’m writing up my best knowledge here, and I’m going to spread it to as many people as possible to get feedback from the 30,000+ other iPhone developers around the world.
(more…)

September 12th, 2009 by adam

(this is off the top of my head, probably some glaring errors; it’s intended to give a general idea rather than be authoritative. How do YOU calculate your hourly rate for contracts?)

It seems there’s an increasing number of people around who have no prior experience of this, and are taking their first steps into freelance/contracting while doing iPhone dev in particular.

There are also an increasing number of clients offering impossibly low daily rates. I’m sure some of these are sharks taking advantage of first-time contractors, BUT … I know from personal experience that some are merely naive. Sometimes, it’s just that they are themselves ignorant of the realities of contracting.

So, to help first-time contractors, and to help clients trying to work out why they’re having trouble getting decent people on their seemingly “sensible” budget, here’s some quick thoughts on the standard practice on contract pricing.

By the way, to answer the titular question: Bad ones – about £250 / $350 a day; good ones – about £750-£1250 / (guess, but I haven’t asked any USA guys recently: circa $1200-$1500?) a day; Really really bad ones who have no idea what they’re doing and are probably teaching themselves programming as they go, on *your* budget – about £200 / $200 a day.

(note: the weak (disappointing, but bearable) and the worst (total waste of your time and money) are duking it out on price at the bottom end of the scale, that’s no coincidence. That’s all they can sell themselves on)

1. Salary is not remuneration

By law, in the UK and throughout Europe, companies *must* provide employees with cash and benefits above and beyond their salary. Whatever your official salary, the govt mandates that your employer pays you X% more than that (X varies from place to place and situation to situation).

X is made up of, among other things: “employer” tax, “employer” pension payments, sick pay, holiday pay (typically around 10% of base salary!), local govt taxes, various kinds of mandatory insurance, etc.

Some people get company bonuses as well, often from 1% to 20%.

Of course, at most companies, you also get a whole load of stuff “for free”. The rule of thumb at many companies is that *every* employee costs approx 10% on top of their base salary – and that any bonuses, benefits, etc, are extra on top.

TOTAL: 120%-150%

Finding work is an unpaid activity

Contractors are required to spend some number of hours every month looking for their next contract. This can start simple – trawling websites – but even when a good match is found, the contractor has to take UNPAID time off work to speak to recruiters/hiring managers, attend interviews, etc.

Assuming everything goes perfectly and it takes you 2-3 days of preparation, search, interviewing, bidding, viewing specs, etc, and you work 2-3 month contracts on average, this is 5% of your working time.

If just one project gets cancelled / doesnt come through, that is immediately doubled. Any slowness on the part of recruiters again increases the cost to the contractor.

TOTAL: 110%-125%

The numbers above are off the top of my head, and are far from complete. When you add it all up, and average over time, the rule of thumb for experienced contractors is that your hourly contract-rate should be at minimum 2 times your hourly employee salary, and as much as 3 times.

This is getting pretty long for an LI post, and I’m sure there’s a lot wrong with it, but hopefully it’s enough to give people an idea of the realities of the situation.

July 14th, 2009 by adam

If you’re in Brighton this week for the Develop conference … there’s a few places left at the free networking/talks event we’re doing tomorrow night:

http://upcoming.yahoo.com/event/3017732/?ps=6

(if you can’t make it, I’ll get all the slides on-line afterwards, so long as the speakers don’t mind)

…although we’re getting very close to capacity. Some people probably will change their minds and not turn up, so it might be worth coming along anyway, even if there’s apparently no space left (and the venue have said they can make room for up to 10 more if they have to, althoguh it’d be a real squeeze, apparently).

PS: the organizers of the Develop Conference manage to be arrogant, rude, ****s for the third year running. They didn’t even deign to respond to my offers to schedule this event at a time that would be least conflicting with their evening schedule for the conference. I am constantly amazed at how many people they manage to piss-off every year, and rather sad, because I suspect it’ll gradually erode more and more of the value of the conference (all the people who refuse to come back, or refuse to speak in future) – and that would be a huge shame, because a summer conference in Brighton is great thing. If they can manage to stop being such ****s and doing their best to screw it up. Sigh.

PPS: FWIW, my reference to “third year running” is based on the things that I know they did / said to friends and colleagues in previous years. I learnt early on to expect nothing but rudeness from them, although I’ve been studiously polite each year, giving them the benefit of the doubt. Perhaps foolishly – but I hoped they might, you know, learn some basic courtesy at some point. Not yet.

</rant> ;)

June 28th, 2009 by adam

Now I’ve recovered from GDC illness, I’ve got a little free time again, and I’m starting one of the iPhone games I wanted to write. This is a “for fun and learning” project, so it’s deliberately chosen to be low maintenance / easy to make a first version / easy to extend later / etc. I need artists, designers, quest-writers, and programmers.

Well, I don’t *need* anyone; I can do this all myself. But I’d rather do it with other people, and I thought there might be some hobbyists reading this who’d like to do something similar.

EDIT: there’s now a googlegroup for people working on this. You *must* contact me first via email (see below) or your request to join will be automatically rejected. http://groups.google.com/group/dmclone
(more…)

June 25th, 2009 by adam

Really? O, RLY?

Well, no, probably not – but this is the kind of opening statement I often make at industry-conference parties. In this rare case, at LOGIN this year, I was showing something on my laptop at the time and happened to *type* my opening salvo, rather than just say it.
(more…)

June 10th, 2009 by adam

Microsoft Office:

  1. Costs stupid amounts of money
  2. Isn’t very good
  3. Is only available on windows
  4. …but “usually” works

OpenOffice:

  1. Is completely free
  2. Is an almost exact clone of Microsoft Office circa Office 2000/XP
  3. Is open-source (so that sometimes you can easily fix it yourself, quite surprisingly!)
  4. …but apart from the Microsoft Word part, “often doesn’t work”

I’ve been using OpenOffice’s Word clone as a complete replacement for Word for the past 3 years, and it’s been perfect. Previously, I used to use Word *and* OpenOffice, because the latter had some big bugs left in it.

Sadly, OpenOffice’s Excel clone is … often shockingly buggy. I won’t go into the details. But this post is about one missing/broken feature in particular: OpenOffice by default saves / exports XML which (for most people, and all simple uses) is unusable/unreadable – and is very hard to convert with XSLT. Read on for a script that will fix this for you…
(more…)

June 2nd, 2009 by adam

(aka “why do my include/require/include_once/require_once files not work / seem NOT to be included, even though they are?”)

PHP has a mechanism for including files inside each other. The architects of PHP didn’t really think much about what they were doing with a lot of the core language features (witness the foolishness over Register Globals), and file import/include/require is a classic example.

This is one of the most fundamental features of the language, and it’s screwed up. It “seems” to work, so long as you write simplistic enough / small enough apps. The bigger your app, the more likely it is you’ll discover how poor this part of the language is.
(more…)

April 5th, 2009 by adam

I’m just finishing up a quick PHP project at the moment, which allows anyone to register an account – so as the final step before launching it, I needed to add some form of CAPTCHA system. I tried a couple of 3rd party ones and source code ones and none quite worked for me. This post gives full source for a simple user-friendly photo-based CAPTCHA in PHP. Use at your own risk – but it’s short and easy to integrate.

NB: this was more a quick-and-dirty practice exercise than a serious attempt at a CAPTCHA. I don’t believe in CAPTCHAs, generally – but if you ARE going to use them, it’s best to have a lot of them in the wild, so it’s harder for crackers to do “crack once, spam everywhere”. See the section at the bottom for links to suggestions for other people’s CAPTCHAs that I reckon would be better for production use if you can get them to work :).
(more…)

April 5th, 2009 by adam

I had to do some iPhone prototyping recently, and we had a trial copy of Unity to hand. I thought this was a great excuse to try using it. First impressions of the editor/IDE/environment – at least on OS X – are not good.

NB: In general, in terms of what can be done with it etc, I’m a fan of Unity. But I’ve never developed with it directly myself, and I’m now finding it surprisingly painful / steep learning curve.

Need to know basis

None of the built-in tutorials work, flat out, because the startup code has apparently changed substantially since they were written. The tutorials keep talking about things like “create a new project; by default it will X and Y and Z” but Unity no longer does any of those by default. Sadly, the tutorials don’t tell you how to get any of those manually – because, you know, they’re done for you by default, why would you ever need to know how to do them by hand?

File Association Theft

I was also *extremely* unhappy to discover a short while later that Unity has stolen the file association for PHP files. Under OS X (thanks, Apple) managing file associations is a surprisingly irritating business, as bad as with Microsoft Windows (Apple deems users too stupid to be allowed to simply edit associations – but applications are allowed to overwrite each other with absolute trust from Apple, and no user intervention allowed), so this is a pain to fix. In particular, I have an entire *suite* of applications and IDE’s for doing web editing, including a specialized high quality PHP IDE. Not any more; Unity has clobbered that with a crappy text editor that does nothing more than basic syntax hilighting. This is pretty offensive: firstly, don’t steal my files without asking, and secondly – give me back my IDE!

NB: I have no idea how it has done this, but Unity appears to have overridden OS X’s systems for file association management – following the standard procedure (e.g. here) has no effect, and Unity keeps stealing control of the files immediately that you confirm you want to give the assocation to some other app.

At this rate, if I can’t find out what it’s done to my OS and undo it, I’ll be uninstalling and deleting Unity with extreme prejudice in the very near future. Sure, this is partly Apple’s fault for assuming all apps are perfect and all users are not, but at a simpler level I just cannot afford to have a non-functioning development computer just because of one badly behaved application.

April 4th, 2009 by adam

Sadly, the code snippets on MySQL’s main website for PHP are mostly untested and buggy (try running them – half of them don’t execute because of silly mistakes).

After much trial and error, here’s one that *actually works*:

// Missing feature (?) from MySQL: find the list of valid ENUM values for a given ENUM
// (actually, returns all the value-arrays for ALL the enum fields in a given table, by name)
// ---------------------------------------------------------
function fetchEnumValuesForTable( $tablename )
{
	global $db; // assuming you're using PEAR:DB here, and throughout (I use it, or MDB, exclusively)

	$enumresult = $db->query("SHOW COLUMNS FROM $tablename");

	// Makes arrays out of all ENUM type fields.
	// Uses the field names as array names and skips non-ENUM fields
	while( $enumrow = $enumresult->fetchRow() )
	{
		extract($enumrow);
		if (substr($Type, 0, 4) != 'enum') continue;

		$Type = str_replace('enum', 'array', $Type);

		// Add to array
		eval( '$tmp = '."$Type;" ); // I'm not sure why, but I had to do this
		// intermediate step to get it to work

		$results[$Field] = $tmp;
	}

	return $results; // returns an array mapping each enum's "column name"
	// to "array of elements valid fo that ENUM"
}
February 26th, 2009 by adam

You would think this is easy, seeing as how it’s an essential, simple, part of any programming project. HA! You obviously haven’t used Apple’s shockingly bad IDE (Xcode) much, have you?

You can read the extremely widely-linked blog post – http://www.stormyprods.com/blogger/2008/11/using-static-libraries-with-iphone-sdk.html – which is incomplete, and doesn’t work properly if you want to do auto-updates when source changes (which, in most cases, you do). Unfortunately, it doesn’t give any pointers to making linked projects work. I don’t blame the author for stopping at that point, their solution “works”, but I wanted to get the full benefits of auto recompilation.

You can google to try and find some documentation from Apple. I can’t find any, although I can find lots of other people on forums asking for documentation on how to do it themselves.

Eventually I worked it out, after hours of trial and error, and reading as much of the Xcode docs as I could find that seemed to relate to what was going on.

  1. Make a new project to hold your shared library
  2. Put all the .m and .h files for your library in that project (drag/drop them to the groups and files list)
    • XCode “feature”: it will by default fail to copy the files, even though that means everything will break later on, when you delete the originals. You need to tick the “copy files if necessary” checkbox)
  3. Create a “Static Library” build target
  4. Drag the .m files *only* to the static library build target’s “sources” twisty
  5. DO NOT DELETE THE FILES FROM THE MAIN PROJECT (because you’ve just created references, not copies, although it doesn’t tell you that … so Xcode will silently delete them everywhere, and OS X still doesn’t support undelete; Sulka tells me that Undelete will be coming to OS X in the next version. Oh, how I laughed)
  6. DO delete the files from the main Build Target
    • (again, they’re not actually files there, just references, so “deleting” them merely gets rid of the reference, not the file)
    • is this another bug in XCode? It seems strange that you use the “delete” funciton to do something that isn’t really a delete
  7. Click the NEW build target (the static library) and right click and select “build”.
    • XCode “feature”: if you highlight the thing you want to build, and hit Cmd-B to build, it WILL NOT BUILD the selected target, it will instead build the main target and ignore the target you actually wanted built
    • The *only* way to make cmd-b build the thing you want is to change some of the options on the Target dropdown at top left of the window – but you’ll have to change it back and forth each time you want to build somethign different with cmd-b … there seems to be no context-sensitive Build command in Xcode (bug?)
  8. If you want to test that your static lib built correctly (hint: you probably do)
    1. Add the static library to the main target
      • XCode bug: you can add the static library to the “direct dependencies” section. This has no effect; don’t do it. The static library MUST be added to the “linked libraries” section, i.e. the bottom panel of the General tab of the Inspector for the Build Target
    2. Write some code that uses your static lib – I suggest putting it in the app delegate class that Xcode auto-generated when you created the new project – and try building the main target (you CAN use cmd-b for this … unless you switched targets above, in which case you’ll need to switch them back first). If you have added the static lib in “the wrong place” or created it “in the wrong way” then this will fail with missing class errors etc

    All that has achieved is to compile your source code. No, seriously – it is THAT HARD. Now you have to actually try using it from another project.

    This is where the StormyProds link takes the easy way out (which only partially works): it simply copies the .a file (generated by the compiler) to somewhere on your hard disk, and has you hard-link to that file from other XCode projects. This will work; but it will also get out of date rapidly, and cause all sorts of bugs if you forget to update it. It will never auto-compile when there are changes.

    What Apple wants you to do (and for once I agree with them :) – this makes sense for most developers who aren’t using an external build system) is to link the projects directly, so that changes in one cause the other to automatically recompile *if necessary*.

    NB: for all my disappointments with Xcode, this is one feature I think has been extremely well done – it handles “links” between discrete Xcode projects extremely well, and (although the menus and docs for it are a bit hard to find) it mostly Just Works.

    1. Link the two projects
      1. Following Apple’s instructions here: http://developer.apple.com/DOCUMENTATION/DeveloperTools/Conceptual/XcodeProjectManagement/040-Files_in_Projects/chapter_5_section_7.html#//apple_ref/doc/uid/TP40002666-CJBJHJCJ – i.e.:
      2. Open the project that will import the static library
      3. Go to the “Project” menu and select “Add to Project”
      4. Find the .xcodeproj file on your harddisk that representst the other project, and select it
      5. Check it worked:
        • At the top of Groups and Files panel, you should see a blue twisty for your project, and just inside it a blue twisty for your imported / linked project
        • Inside the second twisty MIGHT be a .app file (representing the main target of the imported project, which you won’t need – you MIGHT have created a project wihtout a main executable, or deleted the spec for it, but by default you’ll have this)
        • Inside the second twisty should be a .a file (representing the static library from the imported project, which you DO NEED)
    2. Make the secondary project import the compiled static library from the first project
      1. Drag the .a file from inside the second twisty, and drop it inside the “Link Binary with Libraries” section of the main Build Target of the main project
        • DO NOT drop it anywhere else in the Built Targets section – it will work, but will have no effect (you do that in the next step)
        • If you do it correctly, you should see the static library appear with the same icon as each of your included Frameworks (all iPhone projects have at least 2 Frameworks normally: UIKit.framework, Foundation.framework), and appear right next to them in the same twisty underneath Build Targets
        • ALSO open the inspector for your build target and add a second dependency in the main dependencies section to the static lib – NOT the app – from the imported project.
        • (if you don’t do this, you’ll see weird things like the build compiling for iPhone, but not for the Simulator, for no apparent reason)

    Finally … drag and drop the header files from the original project’s location in Finder into the new project’s source folders. Do NOT check the “copy files if necessary”. Xcode will do a reference / softlink, so that changes to the header files in the original project are picked up. NB: you will need to do a drag/drop each time you add a new header file to the original project.

    (You *might* be able to get away with putting all the header files in a sub-fodler of their own in the original project, and drag/dropping that FOLDER into the new project, but … I tried that, and it seemed to sometimes fail to notice the new header files, so I’m not sure I’d risk it).

    Some fun errors:

    Line Location Tool:0: “_OBJC_CLASS_$_ScoreUploader”, referenced from:

    Various causes of this useless error message:

    1. you added a class to the source project … but forgot to drag/drop that .m file into the “Compile Sources” part of the Target for the Static Library in the source project (or you did so, but you didn’t link your xcodeproj’s directly … but forgot to recompile the source project (linking the projects, as described above, triggers auto-rebuilds and you dont see this problem so often))
    2. you had all the source in one project originally … but haven’t deleted FROM YOUR HARD DISK the source files for the source inside the original, main project

    (this is IMHO another bug in Xcode: it silently leaves the files in place, by default, and yet silently (secretly) uses them when compiling – but ONLY when dealing with imported libraries, NOT when dealing with local compilation. Huh?)

    Line Location Tool:0: literal-pointer@__OBJC@__cls_refs@NSMutableList in libhiscorelib.a(XMLSuperParser.o)

    You haven’t added the static lib as a non-lib dependency

    Some things to be aware of

    The header files that you drag/dropped from one project to the other have NOT been copied to the new project and are therefore NOT real files – they are references.

    If you delete the original files (in the statically compiled lib project) then the references in all other projects will vanish; be careful!

    If you updarte the original files (in the statically compiled lib project) then the referneces in all ohter projects will automatically update (with no UI indication of this).

    Unlike most normal IDE’s, there is no obvious UI indication that the files are not inside the current project (you can check by doing cmd-i on any of the files and looking at the value of the “Full Path” field, but otherwise you won’t see a difference).

February 26th, 2009 by adam

http://upcoming.yahoo.com/event/1917163/?ps=5

If you have any interest in iPhone development (you have ideas for apps, or you want to start coding for your iphone, or just want to meet other like-minded folks over beers), then come along.

Bring friends. Bring iPhones (I’ll bring my laptop so you can download and try my current work in progress)

If you’ve got anything you’ve made yourself, definitely bring it along!

We had a quiet first meetup last night, I’ll be adding screenshots / app descriptions for the two apps shown on the night to this post later.

EDIT:

Snooker Scorer

snookerscorer1 This is a simple app that keeps score of a snooker match. You can use it in a club, watching a match live or even following on tv.

Just tap the ball that has been potted. Hit the ‘swap’ icon to swap players. If a foul happens, hold the ‘foul’ icon and tap the ball fouled. Free balls can be added as well through the popup actions icon.

Future additions will make the information line adapt to show the most relevant info such as current or maximum break, difference and points remaing, balls potted in current break, match history, undo mistakes, and whatever else I can think of.

February 18th, 2009 by adam

Disappointing

No spam filter (there is one, allegedly, but it’s invisible, non-configurable (!), and missing obvious spam words)

(there are comments on the official forums from 3 years ago saying “we need some basic anti-spam tools” and the author replying with “we’re working on it”)

Annoying

No spam controls for reactive processing (banning users, marking comments as spam, etc).

Unforgivable

Each comment can ONLY be deleted one, by one, by one, requiring 6 mouse clicks per deletion!

The concept of a list of comments, and a checkbox next to each, and a “delete selected comments” is now well over 10 years old – and it only takes a few minutes to implement with PHP + SQL. If you ever find yourself making a web app for general usage, please don’t forget this core feature :).

(I’ve been too busy for the past month making actual iPhone apps to finish my free PHP FAQ platform, but watch this space, shouldn’t be too long now…)