top | item 23203699

Game Programming Patterns (2014)

635 points| simonpure | 5 years ago |gameprogrammingpatterns.com

86 comments

order
[+] formalsystem|5 years ago|reply
This is the book that finally helped me grok software design patterns. Gang of four reads like a dictionary while the examples of Game Programming patterns have stayed with me.

If I'm rendering a forest of course I don't want to copy the data for trees a 1000 times so of course I need to use the flyweight pattern

The decoupling patterns chapter is particularly good and will help you understand how to turn each entity in a game into a server which sends events to other entities. That way you end up with many small pieces of a code as opposed to a single giant game loop. The entity component system (ECS) is one of the main reasons why programming games in Unity is so pleasant.

If it wasn't obvious by now, this is not a book about game programming patterns it's the best book on software design patterns that I've ever read. Most software design books seems to think I'm only interested in designing accounting or banking software, why not a game?

[+] anchpop|5 years ago|reply
> The entity component system (ECS) is one of the main reasons why programming games in Unity is so pleasant.

I agree programming in Unity can be very pleasant. To avoid confusion, I wanted to point out that traditional Unity programming isn't really a typical example of an ECS. Unity's system actually lacks most of the performance benefits you can get from one. This is relevant because Unity is actually currently developing a "real" ECS architecture they call DOTS (data oriented technology stack).

[+] mikekchar|5 years ago|reply
The GoF book is literally a dictionary. I wish more people realised that. It is an attempt at describing a specific "pattern language". A "pattern" is a solution to a problem that comes up repeatedly in different contexts. For a pattern to be a pattern it there must be a problem you are trying to solve. There must be a context in which you are trying to solve the problem. It must describe the solution in the context. It must describe in which contexts the solution is appropriate and in which contexts it is not appropriate. It must be a solution that is well known and widely used (this bit always surprises people -- usually there is a rule that there must be at least 3 unrelated implementations of the solution in the wild). Finally, for a design pattern, the solution must be in the design domain and not the implemenation domain (drives me crazy when people say that they don't need design patterns because they have a reuse library).

A pattern language is a collection of patterns where the use of one pattern commonly implies the use of other patterns. In other words, if you use one pattern in a specific context, then likely certain other patterns will also be useful. Importantly, there are situations where you want to avoid using certain patterns with certain other patterns. The intent of a pattern language is describe these related patterns and how the work (and don't work) together.

The GoF book was an example of a possible pattern language for object oriented programming. It was never intended to be an exhaustive pattern language, or a recipe book for implementations. It was simply an example of how you might go about making a pattern language in that domain. It was an amazing achievement because it was the first serious attempt at creating such a pattern language.

Unfortunately, not many people have actually read the GoF book end to end and therefore don't really understand what it was for.

[+] phreack|5 years ago|reply
It's hard to understate how much game programming helped in my career. All at once it helped me grok not just patterns, but also Calculus ("wait... isn't this for loop very much like an integral? is that what they actually were all along?!"), Algebra, OOP, Discrete Math and even got me out of a rut after a very boring and stale couple of years.

I very much recommend working on graphics and games to every programmer and CS major who hasn't already!

[+] LudwigNagasena|5 years ago|reply
The MonoBehaviour pattern is similar to ECS (both follow composition over inheritance), but there are some crucial differences IMO. In case of monobehaviours there are no systems as such and components aren't mere data containers.
[+] gentleman11|5 years ago|reply
Re, events: events are wonderful, but doesn’t it get a bit hard to debug them later on? Whenever I work in a poorly written web application, following people’s random/out of date event chains to fix a bug is just maddening
[+] ElFitz|5 years ago|reply
> turn each entity in a game into a server which sends events to other entities.

This reminds me of event-driven microservices. Is it similar, in principle?

[+] munificent|5 years ago|reply
I know this book! :)

I had occasion to dig through my sales data, so if anyone is curious, since I first put this book out there, I've sold 26,009 print copies and 13,066 Kindle copies. I didn't count the ePub and PDF sales. It's been translated to Korean, Chinese, Japanese, German, and Polish.

It's incredibly gratifying to see it still helping people six years later. I can't wait until I'm through building the print edition of my second book [1] so people can get their hands on that too.

[1]: http://craftinginterpreters.com/

[+] nivethan|5 years ago|reply
Thank you for the book and I can’t wait to get a copy of it! I did the first part in typescript and it’s crazy how much of your java code just works with minimal massaging.

Would you recommend brushing up on C before jumping into the second half, I don’t want to just be copying code and miss the real picture.

Just some a stream of consciousness as I read the book and had my mind blown a few times.

https://github.com/Krowemoh/ts-lox

[+] Kapura|5 years ago|reply
I've been programming in the games industry, first at indie scale and now at AAA, and I use almost all of the patterns described in the book in some way. This is an invaluable resource for people to learn not only the sorts of programming patterns used in games, but also the sorts of problems that game developers are challenged to solve.

I've found that google and stack overflow are now worthless for anything outside of checking syntax for a C++ lambda. Everything else I work on is essentially a novel problem set.

[+] robmaister|5 years ago|reply
I 100% agree and I also work in AAA. On the subject of StackOverflow being worthless... I've been working for 4 years now and I have learned pretty consistently over that time that the best way to solve a problem is to just keep digging deeper into the system with the issue.

You will eventually figure out that either the system has a bug or you used it wrong. And along the way you will familiarize yourself more with the system. (and debugging tools!)

The learning effect of this snowballs the more you do it. I'm a year and a half into a UE4 project and am now the "engine person" who people come to with questions or odd crashes.

I have seen every single pattern this book describes used somewhere within Unreal. They are all super valuable to know especially within game programming where problems are novel and often open ended.

[+] erikbye|5 years ago|reply
> novel problem set

Examples?

[+] mmoll|5 years ago|reply
> Everything else I work on is essentially a novel problem set.

It‘s a rotate! ;-)

[+] dang|5 years ago|reply
See also... the largest previous threads:

2017: https://news.ycombinator.com/item?id=14475489

2014: https://news.ycombinator.com/item?id=7646985

2014 ('now finished'): https://news.ycombinator.com/item?id=7634734

2013: https://news.ycombinator.com/item?id=6004885

About specific chapters:

2018: https://news.ycombinator.com/item?id=17845334

2014: https://news.ycombinator.com/item?id=7543158

2014: https://news.ycombinator.com/item?id=7466711

The first thread was https://news.ycombinator.com/item?id=874080 from 2009, and the discussion is about how incomplete everything is. That's interesting, because how many items with a discussion like that ever actually do get completed?

If I missed any interesting discussions let me know and I'll add to the list.

[+] DethNinja|5 years ago|reply
This is one of the best books available on the subject of design patterns. I highly recommend it for all programmers even those not in gamedev.

Keep in mind that some novice programmers assume design patterns are strict rules and you have to copy all idioms, naming rules etc. but they are just simple guidelines, feel free pick them apart and combine them on your code.

[+] rectang|5 years ago|reply
According to the "Game Loop" chapter, the "intent" of the Game Loop pattern is to "Decouple the progression of game time from user input and processor speed."

http://gameprogrammingpatterns.com/game-loop.html

The chapter goes on to assert:

> Game loops are the quintessential example of a “game programming pattern”. Almost every game has one, no two are exactly alike, and relatively few programs outside of games use them.

It seems to me like audio programs would typically be organized using something very close to the Game Loop pattern, though? A loop with where a batch of data is rendered on each iteration, decoupled from the processor because of the need to match the sample clock.

Is there a resource out there that describes audio programming patterns for organizing the whole program? Most of what I've read describes how to use an existing framework — e.g. how to write a plugin — and while that's not surprising, I'd really like to explore all the possible options for high-level organization of a real time audio app. I haven't ever seen something similar to this "Game Loop" chapter for audio.

[+] mcv|5 years ago|reply
Yeah, I imagine anything that needs to produce output continuously independent from user input, while quickly responding to user input, needs this kind of loop.

At the same time, while most games these days need it, I don't see why a purely turn-based game would need it. If you only produce output when the user gives input, you probably won't need it. Those kind of games are rare these days, but roguelikes are still getting made apparently.

[+] dakom|5 years ago|reply
I had a bit of difficulty with this book. Loved reading it in every way (style, content, clarity, etc.) - but in parts[0] of every section I found myself thinking, "wait - of course that's what I'd do... but that's just, like, the thing to do... why is it a pattern? Does it really matter if I call it that pattern or if I don't know the pattern name?"

Maybe it's because I didn't learn coding in university, or because most of my career has been spent in very small teams with little need to use pre-established jargon, but I get slightly annoyed when I see discussions about this pattern or that pattern and I have no clue what they're doing, even if I've myself used that "pattern" dozens of times without knowing the accepted name for it. YMMV

[0] the other parts would be when it got into the nitty gritty of solving a specific problem instead of the generic pattern. For example, propagating transforms using the |= trick. That stuff was great for me.

[+] codemonkey-zeta|5 years ago|reply
I totally agree with you, but I think you're understating the value of the pattern language. Of course any good practitioner will have internalized these "patterns" to the point that they're second nature, in the same way a good carpenter will know all the uses for his tools. The problem with carpentry though is that you require (for the most part) a mentor to pass on this first-hand experience. Programmers benefit from being able to describe our craft with this design pattern language, so that other practitioners can understand very quickly what our implementations look like, and more importantly (IMO), neophytes can quickly and independently familiarize themselves with the patterns to more quickly become experts.

But I don't just think this book is for beginner programmers or people who don't understand the idea behind the patterns. Even competent designers like yourself ought to know the names for these concepts purely for discursive purposes, maybe teaching new engineers or writing blog posts, or designing with other engineers at the same level. The pattern language is just an efficiency layer on human-human communication, which for many of us is one of the most challenging parts of our jobs.

[+] munificent|5 years ago|reply
> I get slightly annoyed when I see discussions about this pattern or that pattern and I have no clue what they're doing, even if I've myself used that "pattern" dozens of times without knowing the accepted name for it.

Having an agreed-on name for it is how you avoid that frustration.

[+] haihaibye|5 years ago|reply
By giving it a name, you can refer to it more quickly and precisely with other programmers.
[+] fao_|5 years ago|reply
So far with game programming the most difficult problem I've had is input states. There doesn't seem to be a clean way to manage it that doesn't get very messy, very fast. Even though it should be easy to manage since it's just a state machine!
[+] simonbw|5 years ago|reply
By input states do you mean stuff like knowing whether a key is currently pressed or a mouse button is currently held down? Could you explain what you mean by it gets messy?
[+] softfalcon|5 years ago|reply
Yeah, before you know it, you’re in the land of colliding mouse down events.

Best I’ve been able to do is group interaction views together (think inventory and character menus vs the character controller).

Separate these view groups so they are triggered by a mode state using an event system that tells each view group which is active.

Only update the active view group.

This isolates each view group to receive mouse/key events by itself. It also keeps menus that interact with one another consolidated together in one place. This helps you reason out the mouse/key events more easily since you know this view group won’t disrupt the other inactive view groups.

Within a view group though, a focused control pattern is a good idea. A simple way is via hit bounding and z-ordering. The top-most, mouse over bounds control is active to receive click events. Everything else is ignoring input.

tldr; hierarchy your input controls into groups so you can ignore the input on inactive/not visible ones.

[+] krapp|5 years ago|reply
Have you tried SDL2? I don't know what your criteria for "messy" is but its event stack makes it pretty straightforward to get input from the mouse, controller and keyboard.
[+] gww|5 years ago|reply
I have always wanted to program a 2D game engine in C++ for fun. Mostly as a learning experience but whenever I decide to do it I get intimidated trying to figure out how to design it and give up. Does anyone have any recommendations of resources to get over figuring out how where to start?
[+] markus_zhang|5 years ago|reply
My advice is to follow gaming history and reuse engine code as much as possible. Use SDL2 as it is barebone and yet privides you sophisticated tools.

Here is a list of 12 games that I picked because I'm biased towards RPG but you can definitely choose your own wishlist.

Part one: Warm up and basic input, audio and video.

Pong, Snake, Tetris, Breakout, Galaxian, Frogger.

Part Two: Scrolling screen, levels and overall game architecture:

Super Mario, Gradius, Twinbee

Part Three: RPGs which are more or less "complete" games and need some tooling:

Ultima III, Wizardry I Japanese version, Dungeon Master

Part Four: Just keep practicing. You already graduated and can do whatever you want!

Also don't forgrt to read Masters of Doom which will give you tons of inspiration. You can actually walk Carmack's route as well. His first commercial game is an Ultima spin off called Wraith.

[+] skocznymroczny|5 years ago|reply
A common recommendation is not to write an engine, but to write a game instead. Create a Pong game. Create a 2D space shooter. Create a simple Mario-like 2D platformer. Now take the code that is shared between all three projects - there's your game engine. Just extract that so that it's nicely separated and easily reusable in future projects.
[+] meheleventyone|5 years ago|reply
Pick a simple game and make that game. Pick a new game and make that game. Take the things that fit the second game from the first game. Now you have at least some basics that do input, rendering and audio. Pick a bit to improve towards your target.

Making “an engine” isn’t really something you can do unless you have an idea about what making a game actually means. Then you can work out what it is that you actually value.

[+] krapp|5 years ago|reply
Just start anywhere. You're going to end up throwing it all out anyway. Accept that failure is the path to success and just do it.
[+] friendlybus|5 years ago|reply
If you can tolerate switching to C#, XNA (later transferred to MonoGame) is a great framework to cut your teeth on. I started there, it may be a little of out date, I'm fairly sure MonoGame is still maintained.

There are a bunch of resources out there for XNA.

[+] tgb|5 years ago|reply
What's the gist of the setup for how a complex RPG rule system gets coded up? Like in D&D or a Diablo-like, you have base stats, equipment or classes modify those stats, sometimes the modifiers depend upon the circumstances, and maybe the modifiers get modified. So clearly you don't want to have a Belt of +4 Strength just do wearer.strength += 4 since at some point you'll have to take off the belt or are in an anti-magic field, etc. But what's a good and/or standard design for encoding all that kind of logic?
[+] munificent|5 years ago|reply
I've run into this exact issue in my roguelike [1]. I don't think I have a fully baked solution yet, but the direction I'm going [2] is a combination of the Observer pattern and caching.

For derived stats, it's not enough to just always recalculate its value from scratch every time you access it. At least in my game, I also want to tell the user when the value of a derived stat changes. If you equip a piece of armor that raises your strength, I want the game to tell you "You feel stronger!".

So each derived stat stores its current value and then has a refresh() function to recalculate itself. The stat is refreshed at the end of each turn. It recalculates the value and then compares its previously cached one. If the value changed, it logs the result and then updates the cache.

[1]: https://github.com/munificent/hauberk

[2]: https://github.com/munificent/hauberk/blob/master/lib/src/en...

[+] MrStonedOne|5 years ago|reply
You have calculate it on read based on the user's state at that time.

getStr() { output = this.str;foreach (equip) output += equip.getStrMod() }

[+] lachlan-sneff|5 years ago|reply
I haven't had time to read the book yet, but the web version of it is just so beautifully displayed. So, kudos for that :)
[+] munificent|5 years ago|reply
Thank you, I put a lot of time into the design and CSS.
[+] Sprakle|5 years ago|reply
Does this book have much relevance for someone already working in an existing engine like Unity?
[+] zwaps|5 years ago|reply
I think it's probably good to know for every engine and besides, it's a beautiful book.

That being said, armed with my baby knowledge of programming patterns, I then did find it frustrating that today's engines are very high level and quite opinionated about how you code. Take for example Godot. It's not 'quite' an ECS and there are certain ways to script things which you should follow. How to fit the patterns from this book into a Godot game is a whole other ballgame.

This book makes me want to write my own engine. Not to deal with the technical details, but to be in control of the program logic. This excellent book makes you want to worry about the stuff that engines abstract from in their own special way. That's not efficient from the standpoint of getting a game done - things are done in Unity or Godot in their specific way for good and battle-tested reasons.

[+] trynewideas|5 years ago|reply
Yes, absolutely, 100%. It's engine and language agnostic; many of the examples are written in C++ in lieu of pseudocode, but he also goes into where C# differs in behavior enough to affect the pattern.
[+] marvinblum|5 years ago|reply
Ah yes I remember. This site teached me so much, even if I'm not doing game programming anymore. It shows some generally useful patterns and algorithms not only relevant to game development. So if you're a programmer, give it a shot!
[+] rahulpyd1|5 years ago|reply
This book is well written. It has the right amount of detail and simplicity. When I started out in game development the book helped me lot in understanding game development.
[+] toastal|5 years ago|reply
I wish there was a complete FP engine. Most 'patterns' in FP are (surprise) just functions. There's a lot of blogs with some simple examples from scratch, and that's really cool, but there's a lot of room for a complete system. What isn't needed is all this encapsulation and inheritance I see in many other big engines.
[+] gentleman11|5 years ago|reply
This book is fantastic. If the author is reading this, please don’t feel shy about expanding the chapter on state machines. It is an extremely deep and valuable subject with a lot of “get your hands dirty” learning to do. Thanks for writing what you did!
[+] edem|5 years ago|reply
This book is pure gold. I recommend this to any programmer!