Game Programming Patterns (2014)
gameprogrammingpatterns.com
gameprogrammingpatterns.com
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?
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).
In terms of just mental overhead any form of composition is useful be it Components in the Unity sense or Components and Systems in the ECS sense.
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.
I very much recommend working on graphics and games to every programmer and CS major who hasn't already!
For reference, the ones I used to love and seem to still be kicking were Phaser.js for web games and Libgdx (on Kotlin) for mobile/desktop. Both were incredibly fun to learn, and I went at it very slowly on my own pace with a clear, small-scoped, end game goal each time. It was very hard but worthwhile to not let myself fall to scope creep, and after a couple of completed prototypes I felt ready to tackle 3d. I got some projects on C# that used Direct3d to draw things with triangles and went nuts trying to implement the concepts I read about in books like realtimerendering.com
I know it all looks daunting at first, but always remember that it's supposed to be a very long, very fun journey, meant to satisfy your intellectual curiosity at every step of the way. Games and graphics are one of the most rewarding problem spaces since every time that you learn a new concept and get it working, you get to see it and play with it and it's the best feeling ever!
And while I'm here I want to share the most wonderful tutorial on how to build hexagonal grids for games and things, in case you want to do something hexagonal at some point like I did, from what I think is one of the best educational resources I've ever seen: https://www.redblobgames.com/grids/hexagons/
Cheers!
This reminds me of event-driven microservices. Is it similar, in principle?
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.
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.
The introduction chapter suggests this exercise:
> To get some practice with pointers, define a doubly-linked list of heap-allocated strings. Write functions to insert, find, and delete items from it. Test them.*
If you can handle that, you should be fine for the rest of the book.
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.
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.
>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!)
I identify with this so much. It's a different kind of programming, where you're finding the source of the bleeding instead of trying to just bandage the wound, which is much more what I encountered in the tech industry.
But it's never been about debugging deep problems. Nobody can look at what's happening in your debugger. It's mostly useful for how to use specific libraries and frameworks or basic language features.
Examples?
I can look at our other code, I can look at other cameras in game & film, but ultimately it's just me down there in the code deciding whether the pull the camera in or pitch down or lengthen the lens or how to handle blends or whatever.
We had one dev and an animator spend months getting our camera system to the point where it felt natural. Definitely one of those things that takes a ton of work and only gets noticed when it goes wrong.
It‘s a rotate! ;-)
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.
Even reading his writing about writing risks reducing you to tears.
http://journal.stuffwithstuff.com/2020/04/05/crafting-crafti...
I have been amply rewarded by both sales and really really nice words from people over the years, so I think I've got more awards than anyone could ask for.
What's interesting is how circular the process is. If my first book hadn't been successful, I certainly wouldn't have written my second book, so I owe its existence to many other people.
https://tylerayoung.com/2017/01/23/notes-on-game-programming...
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.
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.
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.
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.
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.
Having an agreed-on name for it is how you avoid that frustration.
First of all - I want to say thank you. I really really did enjoy the book and smiled at the picture with your dog (as well as all the programming stuff ;)). Honestly, I've recommended it to others enthusiastically and got a lot out of it. Thanks!
I totally agree with what you and others said. I get it - and the only way I've been able to get away with not knowing the names of some of these patterns is precisely because I've only worked in very small teams and had a lot of autonomy. Also, for async/internet discussions I often have enough time to look it up if someone uses the jargon, and because I've encountered the names/concepts before (like in your book) it doesn't take long to catch up to the conversation.
That said - I'd like to explore one more avenue... is it possible that not seeing things as patterns allows for a more intuitive grasp? e.g. if I want to do things based on some current state, yeah I could reach for "statecharts" or "finite state machines"... but thinking of things as enums with switching based on the enum value might lead to a more intimate grasp of what's going on, and clearer insight into the different ways to hack around the problem? That might not be the best example (I've basically described a state machine and then said "how about not using a state machine") - feel free to substitute a better one if the question makes sense.
I guess I'm wondering if maybe there's an advantage to solving these things over and over but not seeing them as patterns? Not saying I'd recommend it.. just, if there's a silver lining to a bit of ignorance?
Yes! I think about this often. There is sort of a Zen or Bruce Lee aspect where thinking of things strictly in terms of named categories can lead to overly rigid thinking and cause you to avoid better solutions simply because they don't have a name and don't seem as "real".
There is a balancing act, though. When we write code on a team, there is a real value to shared understanding of the codebase. Sticking to familiar categories, even at some minor expense of fitness to the task, is probably a net gain if it makes it easier to the entire team to understand what the code is doing and why.
It's also important to remember that the primary reason the Gang of Four wrote Design Patterns and called them patterns after Christopher Alexander's A Pattern Language is because they are not rigid copy/paste structures. If they were, we'd just call them data structures or algorithms.
The fundamental premise of why we call these patterns is that each manifestation of a pattern will appear slightly different, shaped by the context in which it is applied. That's why you don't often see resuable "pattern implementation libraries".
Good literature on patterns stresses this flexibility. Less good literature tends to just say "here's the thing that solves all your problems" and discourages readers from thinking deeply.
I dunno, maybe I'm just overthinking it
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.
Author here: https://twitter.com/munificentbob/
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.
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.
There are a bunch of resources out there for XNA.
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...
Worth every penny.
getStr() { output = this.str;foreach (equip) output += equip.getStrMod() }
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.
Do it!
I've been working on a game engine for several months now. It's a similar kind of hell to working on an OS (though easier to debug...until you start using threads), but it's fun.
int destY = unit->y() - 1;