Category: Uncategorized

  • Resource Mangling (with a side order of Wibble Principle)

    Sometimes even the most basic seeming thing in a game isn’t so basic. It seems so obvious that you just make it without a second thought, and then it sits there being Just Good Enough™. While this is fine, if you’re anything like me Just Good Enough™ will fester in the back of your mind because it’s now Just Not Right™.

    This post is going to be a bit Unreal-centric, but hopefully the underlying message will make sense to other places (possibly not even games!).

    Let’s talk about something that I, until alarmingly recently, would just make without a second thought, and would be one of the very first things I would make when starting a game project.

    Let’s talk about good old HealthComponent.

    No I don’t know how to draw “health”, so he’s got eyes.

    HealthComponent is doing some pretty basic stuff. You’ve got a current health level that is almost certainly a number, out of a max health level that is almost certainly a larger or equal number. You subtract from the current health when you take damage, or add if you are healed. If you run out of health, then you’re (probably) dead (don’t get me started). You might also just want to do insta-death, so set the health to zero regardless.

    Honestly? This served me well for many years (hindsight note: actually no it didn’t), so I never bothered to change it. It only gets a bit weird when you have multiple numbery things to track.

    So let’s make it more complicated. Now you want to cast spells. Enter ManaComponent.

    Superficially, this guy looks like a different component entirely. In reality, all I’ve done is changed the words and given him a snazzy wizard hat.

    To really belabour the point: You’ve got a current mana level that is almost certainly a number, out of a max mana level that is almost certainly a larger or equal number. You subtract from the current mana when you cast a spell, or add if you drink an ether. If you run out of mana, then you (probably) want to inform the player. You might also just want to do insta-OOM, so set the mana to zero regardless.

    I could go away and put endless hats on HealthComponent and call it a new name. What about Poise or Stagger? What about Encumbrance? What about Experience Points (yes, I’m assuming that you can lose Experience Points, which is a thing we did in the dark ages)? What about Ammunition for your vast array of guns? What about Money?

    At which point, you’re probably thinking “Money? Pix has gone insane.” No really, if it’s a number, you can put a different hat on the same underlying structure, and have that structure represent something else.

    Wibble Principle

    I’m going to take a step back here to show a little creative thinking exercise that I tend to use when I’m trying to unpick something that feels wrong in code.

    Put simply, I take the description of the feature, and start replacing the proper nouns with a nonsense word. I like to use wibble, because it’s fun to say. Somebody a lot smarter than me called it a ‘metasyntactic variable’, I call it Wibble Principle.

    So let’s try and make a wibble component.

    So why wibble? What is wibble? The beauty of wibble is: we don’t care what wibble is. It doesn’t have to mean anything. I could have used plerbs, or blorts, or fliblets. The point being, that wibble can replace all of the more specific concepts like health, mana, poise etc. and the underlying structure still holds.

    We still modify wibble when something wibbly happens. We still notify the player when they are out of wibble (what does that even mean? Do we care? Nope!). I added notifying the player when they have a full complement of wibble, because it seems useful regardless (why not wibble harder when your wibble is maxed?). We also can force wibble to the minimum or maximum values, and the minimum doesn’t even need to be zero.

    I use this when I’m trying to extract the core structure from a rather fluffy gamey feature, and that generally results in a) a more flexible design but b) more confused people around you if you actually mention wibble. Don’t actually call it WibbleComponent.

    The Final Structure

    Knowing that we can extract a whole bunch of concepts (i.e. anything that could be represented as a bar, or a resource gauge, or a percentage, it’s just numbers) out into one generic structure means that in Unreal-land, we can just have one ActorComponent that houses more than one of these ‘resource’ structures. In effect, we have our HealthComponent with all its different hats in one place, under one component, and the hat becomes all that it should have been in the first place: A Decoration, or an Identifier.

    But why?

    I’ll be honest, if you really want to have multiple functionally similar (or even identical components) to manage different resources, then I won’t stop you. However, consider the following:

    • What if we want to redirect health damage to a depletable shield? How about if we only want to redirect a portion of the damage?
    • What if we want to lose money instead of health when we’re wearing specific armour?
    • What if we want casting spells to cost crystal shards (or whatever) instead of Mana, but only if you’re a Crystal Wizard?
    • What if you actually do have Wibble, and if you have wibble, it’s consumed instead of something else?

    Multiple components here becomes messy, you’d need to have something that comes in and marshals the function calls to the correct redirected component. It’s doable but it’s either a function on the character, or yet another component. If you have all this under one component structure, you can just modify whichever resource that the incoming damage is set to modify. You don’t have to care what the modification is or where it came from. Just that This Damage Changes This Resource.

    The flip side of this is that depleting a resource becomes a listener that is waiting for the deplete, and the actual “what happens” bit lives elsewhere. So e.g. Death does not live on the HealthComponent, just “I have died, please do something about this”. Given how complicated and messy Death can be (I swear I’m still talking about games), this is actually more of a blessing in my eyes.

    Further Wibbly Applications

    Once you’ve embraced wibble (or nonsense word of choice), it opens up other possibilities. You’ve boiled your system down to its base principles, and you’re free to think of all of this in a systematic and abstract way.

    Which means you can get creative with it. Or at least make yourself laugh.

    As a final takeaway, what this model of resource mangling can produce is: You could model a transaction in a shop the same way that you could punch someone in the face.

    • You: “Hello shopkeep. Just these please!”
    • Shopkeep: “That’ll be £5”. And then he punches you square in the face.
    • You don’t even flinch, it didn’t hurt. But you look in your wallet and £5 is gone.
    • Shopkeep: “Cheers mate, see you next time!”
  • The X/Y Problem (as illustrated by poorly drawn horses)

    I love the X/Y problem, but I don’t love when people fail to apply it, or even haven’t heard of it. It is, in my opinion, one of the fundamental things to learn in programming, and that goes double for games, especially when working in a team.

    So what is it?

    The very dry, very boring explanation is: when somebody asks for a feature, always ask “why”, rather than just accepting the “what”. More detail from a smarter human here: https://xyproblem.info/, I’m just going to focus on making this amusing.

    Fair warning: If you’re not good with the idea of using stupid metaphors in place of actual software features, you might want to run away now (screaming optional).

    On with the horses

    You’ve just received a very strange request for a feature: somebody has strolled up to you and said “I want a pony!”. They’re serious, a pony is what they want, and what they need, and they’re very clear about it being a capital P pony.

    So you set out to make the best damned pony you reasonably can. You’re probably thinking something like this:

    Original public domain image from The Rijksmuseum

    The experienced beings in the audience may have spotted your first mistake. You didn’t enquire what the pony was for, why do they want it, and why a pony.

    I get it, it’s Friday afternoon, it’s 4.30pm, the person who requested this has a history of requesting Weird Stuff, and you’re still halfway through their previous request of 500 teacups, one digestive biscuit, and curiously, no tea. So you just get on with it.

    You’re happily carrying on with building your pony, and you get to the point where it’s mostly able to do pony stuff. Problem is, it looks like this:

    This pony is clearly not ready for production, or even remotely finished.

    Feature Requester has been doing some thinking in the meantime, and points out to you that the pony should be able to carry a person. Fine, ponies are supposed to be able to do that, so you add a saddle.

    But Feature Requester comes back, and says “Oh, didn’t I mention it should be able to fly?”. So you backlog actually finishing the pony because if it starts to look even more like an actual pony it definitely won’t be able to fly. Time to add wings, I guess.

    You show this to Feature Requester, who sighs and shakes their head. “I wanted it to be able to go faster than this”, they say with a tone of voice that’s somewhere between disappointment and implying you have the brain of a particularly uncreative iguana.

    But that’s okay, you can augment the flight speed by having rocket boosters. Pony can fly, pony can fly real fast. It’s not particularly safe but at least the rocket exhaust isn’t pointing directly at the saddle. Nobody wants lightly toasted toes.

    Feature Requester is now happy with the flight speed of a traditionally non-flighted animal, and you’re starting to get a little annoyed at how much your Perfect Pony Programming is getting polluted with things a pony isn’t even really supposed to do.

    “Oh, yeah, the pony? It needs to be able to survive without water”.

    Your brain just flashes a massive warning sign that reads simply: “WHAT”. But you carry on, you’ve started now, no point in starting a new pony when you’ve been working on this little guy for weeks.

    In a flash of inspiration, and more than a little bit of idea theft, you give the pony a stillsuit. Now he can make his own water (from something you vaguely remember reading when you were 15).

    Pleased with this compromise, you sit down and start thinking about pulling “finish the pony” out of the backlog. But Feature Requester, bless ’em, is back again.

    “I think the pony should be able to survive without air, that would be easy right?”, they say in a message received at 6.45pm from their phone. You saw it because you’re now massively behind on the pony feature and wanted to do some sneaky catching up.

    You sigh, shake your head, and start designing some kind of pony helmet. It’s trickier than you’d think because a pony has a surprisingly long head and most helmets are designed for something more orb-like.

    Feeling a sense of victory, surely the pony is perfect this time and you can get back to making your perfect pony (with all this weird nonsense tacked on, but we just have to live with it now).

    “Hello!”, reads a message from Feature Requester. Just hello. You start to feel a bit like you’re sinking through the floor.

    You respond with a message that is trying desperately not to say “Please just get on with it, what do you want now?”.

    “I just realised that the pony also needs to be able to carry a week’s worth of cargo. Sorry I didn’t mention it earlier but I only just thought of it”.

    You’re starting to feel a bit sorry for this poor pony, it’s already looking a little bit like it’s begging for just a fresh carrot and a packet of polos. Maybe a nice field to run around in. But you persevere.

    This poor pony is running out of space where you can plausibly add more stuff to it. But with some clever trickery, you work out that you can dangle the cargo like a hot air balloon underneath the belly. It’s all starting to look a bit silly but it still technically fits the request.

    You send your flying, rocket powered, self sustaining, cargo carrying pony off to feature requester. It’s better to confirm that this is what they want now rather than finish the job and have them not want it.

    “Yeah this is perfect!” they exclaim with joy. “I’ll get on with using it right away”.

    You hedge your bets by pointing out that bits of this pony might be quite hard to use, like the wings keep hitting you in the face when you’re sitting in the saddle, or it’s really hard to see over the helmet so you might have to lean to the side.

    Feature Requester isn’t listening, they’re poking and prodding the pony who would really, really like to just go back to the stable and contemplate the meaning of its existence.

    You finally ask Feature Requester what they wanted the pony for, even though now, you’re not sure you want to know. But it’s your responsibility to know, because you have to maintain this pony.

    “Oh, I wanted to be able to go to the moon”.

    So after all of that, what they really wanted was…

    The moral of the story is: When asked for a pony, do make sure that what you actually should be building is in fact a pony, and not a rocketship.

  • Hello world!

    Welcome to WordPress. This is your first post. Edit or delete it, then start writing!