There is No "Right Way"

After a conversation with @gravislizard on twitter, I got thinking
about a particularly common hang-up that a lot of developers from all walks of life struggle with: the
Right Way to implement a particular feature.

Yes, this is another "everything is a trade-off" article, but I wanted to crystallise some thoughts I
had as they apply to gamedev. I'm taking a more programming-focussed point of view because I think
programmers struggle with this the most, but this applies to design, and art, and even marketing choices
as well.

The title is, of course, hyperbole 😅

There might be a Right Way to implement a certain feature in a given context, but there is usually not
in the general case... and boy do people love to fixate on the general case.

This is really hard to accept for most gamedevs, new and old.

For new gamedevs, there are many opinions touted as fact and patterns touted as rules in books,
blog posts, youtube tutorials, and school courses. If there are no globally true set of principles to
code by, how do any of those books get written?

For more experienced gamedevs, sometimes it's as simple as "There must be a Right Way, because I've sure
seen the Wrong Way in practice". We've also had more time to accumulate biases and misconceptions out
in the weeds.

However, the advice on how to write clean/fast/safe code from that clever programmer is still just
advice - guidelines, rather than concrete rules. That terrible broadphase implementation you saw in
a legacy codebase was still just one implementation, and may even have been the Right Way at some
point in that project's lifecycle, or at least seemed like it.

So what?

To give a more concrete example, let use game physics and collision.

I think it's a good example because there's super-obvious trade-offs involved, that most folks
can understand. Also, I've already written about it in my NotGDC'17 article on Bucket Grids 😉

However - this doesn't just apply to physics! This applies to everything. The Right Way to go ahead is going
to depend on what you need, how much time you have, and your level of experience.

To help see how this might apply elsewhere, I'll also provide an analogy to other areas of gamedev for each situation.

Match 3, ASCII Roguelike, Text Adventure

For many games, you don't need a physics engine at all. Implementing some basic equations of motion
for cool particle effects might be a nice thing to add when juicing up the game, but maybe collision
can be ignored completely.

Pros:

No work

Cons:

No physics

Analogies:

No Networking

No DRM

No Localisation

No Control Bindings

Final Destination

Indie Top Down RPG or Platformer

You can often get away with O(N²) loops over the objects you to collide and the constraints to maintain,
and some basic maths to resolve collisions after the fact.

Many gamejam games get away with this, as do many simpler indie titles, and even several older AAA titles
with fewer concurrently active objects.

Pros:

Pretty easy to get started

Room to optimise after-the-fact

Cons:

Won't scale to big simulations without more work

Analogies:

Load all sound effects + textures once at startup

Client-authority send-everything networking

Decoration objects as "fully fledged entities"

This will often be referred to as "The Wrong Way" to do something in some circles.
While you should be mindful of the choice you're making, pragmatic minimalism
goes a long way in many situations. There's a lot to be said for getting it done.

Bigger Metroidvania, Shoot Em Up

For more complicated situations (lots of objects, big levels, bullet hell), you'll probably want
to optimise. This might look like a bucket grid or quadtree, but might also be as simple as
maintaining active/inactive lists in some cases, or only colliding objects in the active "room".

Pros:

Faster to execute for non-pathological cases

Can be added to the simple case if/when needed

Cons:

More engineering work

Can become more complicated to interact with elsewhere

Often some memory overhead (Compute/Memory trade-off)

Analogies:

Occlusion culling and batching for a rendering system

Streaming assets in a big game

Delta compression and influence tracking as part of a networking stack

You want to be sure you actually need to optimise though. Common physics optimisations are
sometimes slower in the easy case - but worse than that, there's simply no point optimising
collision between a handful of objects

Complex Requirements, No Expert On Team

For many games large and small, integrating an off-the-shelf physics solution will be the way to go.
Box2d, Physx, Bullet, Havok... they've all been used in commercial games to great effect.
Stuff bumps against other stuff. Scales well to complex worlds. Can handle detailed constraints.

Job done...?

Pros:

Very robust

Does everything "clever" for you

Someone else's job to make sure the maths is right

Very high bang to buck ratio

Cons:

Added Dependency

Does take some work to learn about and integrate

Can cause platform lock-in down the line if you're not careful

Often less flexible/customisable

Analogies:

"Foundation" Libraries: Image loading, sound, graphics

Networking libraries: ENet, Raknet

Any other middleware.

The takeaway here: if a library can do it better, faster, and it matches your requirements, you
should probably use that library. Just be careful that it actually does match your requirements, or
you'll be in trouble down the line.

Niche Requirements, But You're An Expert

You have a complicated requirement, like a water sim with pressure support that flows around
in your 2d tilemap world, causing cool particle splashes and knocking objects around.

...But wait, there's no off-the-shelf solution available for that!

Such situations usually require a bespoke, often complex solution - perhaps with some judiciously
applied cheating for good measure. If your game world is huge (think dwarf fortress or factorio)
or has something special like a dedicated fluid sim, power grid, collapse system, or real time
deformation, this will be you.

You'll have to find the best way to forge ahead on your own.

Pros:

Can do whatever fancy thing you need it to!

Cons:

Big time/money cost

Risk of failure

Analogies:

Custom rendering systems

Character customisation systems

Procedural generation (levels, dialogue, items, characters)

Niche Requirements, But You're NOT An Expert

(or you're short on time)

You can always fake it 😉

Be careful going into situations that you know/expect not to fully understand, or where
you don't think there's enough time left to do the mechanic justice. This is often where
those systems no-one wants to touch 3 years down the line are born...

However, it's also where a lot of "special sauce" comes from. Going outside your comfort zone
can be hugely rewarding.

Just make sure people aren't going to get hurt as a result! This applies a lot more to games
than to systems handling sensitive data or where safety is at stake!

Parting Thoughts

The process of becoming a "Good Gamedev" isn't an exercise in rote-learning every algorithm,
data structure, trick, hack, and shortcut used in production. You'll pick a lot of that stuff up
as you go, and you can look up almost anything these days if you're stuck.

It's having the understanding to predict which choices will matter,
the confidence to make a choice and stick with it,
the ability to do the hard work when the situation calls for it,
and the humility to learn from the bad choices you inevitably make along the way.