Game programming patterns

I read through the game programming patterns by Robert Nystrom. The web release is free to read online. Reading it through let me highlight the flaws of programming design patterns.

In the book the writer discusses various design patterns that have turned out to be useful in game design. The presentation is fairly unbiased and readable.

I can't help but notice that every design pattern presented is a complication over an otherwise useful concept. At the worst they are implementation details in a language where everything is so difficult that you can't do it directly.

The concepts of this book can be boiled down to few concepts that are central to the game programming. The insights gained can be useful, but the are individually useful and lot of the book's contents could have been elided. I can show this to you.

Command pattern

The command pattern boils down to wrapping a function into a class, so that you can conveniently pass the function across in your code:

class JumpCommand extends Command {
    public execute()
}

This allows you to pass the command around or return it. If you add an undo method, you can store all the commands into a queue to implement undo/redo inside your game. It is all impressive and useful if you look into it with young eyes.

But why go through this all throuble? I could just pass the functions around:

return [jump, 15]

And if I need to undo something, I can produce a pair of functions:

jump = (units):
    previous_y = 0.0
    do = (player):
        previous_y = player.y
        player.y += units
    undo = (player):
        player.y = previous_y
    return [do, undo]

In a good programming language functions are values as much as numbers are. You can pass them around without wrapping them to anything and that is acceptable.

Flyweight

The flyweight pattern illustrates the idea that when you have lots of objects that are similar, you can reduce the storage of them by collecting the things that are common among the objects and store only the parts that are individual in each object. The author illustrates this with the trees in a forest.

Do you really need a pattern for taking a reference from an another object? I don't know. It's so trivial that I shouldn't even bother writing down an example of doing it.

tree_model = load_model()
forest = []
for i in range(300)
    forest.append(object({
        model = tree_model,
        x = random(),
        y = random()
    }))

Queues or logs

The Observer pattern section in the book illustrates how you can decouple your implementation of achievements by letting the other objects produce events into a common queue, or a log, that can be then observed by the achievement system.

It's a very useful concept, but the useful concept here is the queue or an event that the achievement system can track to determine whether an achievement occured, so that the code implementing achievements is not spread across the source. Everything else is plain noise.

Lists, queues and event sources overall are basic primitives in most programming languages.

Expanding out of your language

The book illustrates objects you expand from templates. As in you actually create a game object, give it slots on what can change and expand that template to create instances of the object.

Constructing language-like primitives on top of your programming language isn't as uncommon as you would think. Games obviously have use from this because they commonly create whole small worlds for the user to play with.

State machines

The significant part of the book discusses state machines as a way to organize your program. They are very useful, and provide a good way to organize the game around animations and effects. The state machine forms the game and the transitions trigger animations as they happen.

But state machines are inherently an algebraic construct, and you have practically uncountable ways to implement them with a programming language. You may be implementing state machines without being aware that you are doing so.

Design fatterns

So these are the concepts and design patterns explained in that book. It contains some nice explanations about components, memory management and spatial partitioning.

Rolling out ideas in your head and thinking about them is nice practice. There are lots of theory about state machines, queues and functions. Learning that theory can help in solving the problems you face at programming.

Design patterns are hogwash though. If I were any more cynical than this I would say they were contrived to sell you books rather than help you organize your code.