Hacker News new | past | comments | ask | show | jobs | submit login
Game Programming Patterns (2014) (gameprogrammingpatterns.com)
635 points by simonpure on May 16, 2020 | hide | past | favorite | 86 comments



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?


> 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).


To be ultra confusion avoiding you don’t necessarily get great perf benefits from the merely organising things as per the ECS pattern. You still need to organise your data around how it is used. Which is why Unity uses archetypes which trade fairly automatic organisation based on entities component signature for increased cost if you add and remove components from them (as it triggers reorganising where that entities components are stored). There are other patterns with different trade offs.

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.


Personally, the performance benefits are secondary. It is a lovely way to program to be able to use composition like you can in Unity. If only they didn’t revoke usage rights on their asset store without warning during license updates, I would be a much bigger fan of the company


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.


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!


What would you suggest as a starting point for a regular software engineer who'd like to look into this? See how everything comes together at a high level I mean? Because to someone on the outside, the field of game development appears to be very daunting.


There are a lot of libraries in different languages that are sort of in a middle place between drag n drop engines and programming straight to a graphics API like Direct3d or Vulkan. You should look around for a popular one in a language that you're already comfortable with and read up on tutorials, documentation, and such first.

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!


That site has a rather good walkthrough of pathfinding in general


Starting with something easy, like 2d animations in browser using libraries like pixi.js. From there you can expand on many topics, just focus on one at once, be it shaders, networking (for multiplayer games) or whatever might interest you.


Monogame if you are coming from C# background, or want a fun intro to C#.

https://www.monogame.net/


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.


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


> 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?


Sounds more like actors. And how Alan Kay envisioned what he called object oriented programming at the time.


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/


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


It depends on your level of C expertise. It's not very advanced, sophisticated C, so if you're mostly got pointers loaded into your head, you'll be fine. If a few `` and `&` will leave you scratching your head, it's not a bad idea to practice a little before you tackle the book.

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 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.


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.


>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!)

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.


10 years ago, Stackoverflow was fantastic. I feel a bit like its usefulness has dwindled.

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.


> novel problem set

Examples?


Well, I've spent the past week tuning our boss fight camera algorithms so that the camera does its best to track the boss if they dash across the room or leap into the air. Nobody can really tell me how to do this outside of our company, because nobody else is dealing with a boss that moves like ours, nobody else has the same camera language constraints, and frankly dealing with algorithmic camera motion is not something most programmers ever have to do.

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.


Oh man camera systems.

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.


> Everything else I work on is essentially a novel problem set.

It‘s a rotate! ;-)


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.


Same author as http://craftinginterpreters.com/ Can’t wait for this one to appear in print.


He’s an amazing writer. I couldn’t put this book down when I first read it. At the time I sent him a message saying that it was the best technical book I’d ever read and his response was along the lines of “thanks! It’s the best (though, only) one I’ve written”. I’m glad that’s no longer true.

Even reading his writing about writing risks reducing you to tears.

http://journal.stuffwithstuff.com/2020/04/05/crafting-crafti...


This guy really deserves an award. I wonder decades from now, how many people would look back and say how much these books have influenced them.


> This guy really deserves an award.

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.


You might enjoy this discussion https://news.ycombinator.com/item?id=22788738


If you'd like a summary of the book, my study notes are here:

https://tylerayoung.com/2017/01/23/notes-on-game-programming...


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.


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.


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.


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.


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.


> 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.


Hehe - I wasn't sure which person to reply to... then I realized, it's YOU!

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?


> is it possible that not seeing things as patterns allows for a more intuitive grasp?

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.


Btw, I think this exact concept might have been dealt with a bit in Zen and the Art of Motorcycle Maintenance. I just can't figure out which viewpoint falls into the "classical/analytical" and which falls into the "romantic/intuitive"... an argument could be made on either side, and as you said it's best to master both and find the balance. Food for thought!


Fantastic answer! Thanks for taking the time to respond here - looking forward to your next book :)


By giving it a name, you can refer to it more quickly and precisely with other programmers.


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!


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?


I mean segregating mouse actions. So: Drag, Click, etc. Also handling selection events and so on. I've been using love2d, which basically means you have to set up those manually. Then building a state machine in lua gets very messy.

I dunno, maybe I'm just overthinking it


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.


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.


Loved this book! Reads really well.

Author here: https://twitter.com/munificentbob/



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?


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.


To correct: Carmack's first commercial game is NOT Wraith, but Shadowforge. But the engine is very similar to the one he used to develop Wraith.


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.


Thanks, that does make more sense and seems much less intimidating.


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.


Thanks, I am going to try to start with something easy like tetris.


That's definitely the way to do it. For my first game I built pong.


yes, tetris is not as easy as it seems :) breakout and space invaders are other popular choices. You can make breakout in a weekend (assuming you already know how to program).


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.


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.


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?


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...


There's a combination of patterns. IMO the best way to learn how this stuff works is to look at the code of a production level MMO/MOBA/RTS. Here is a really good one https://assetstore.unity.com/packages/templates/systems/ummo...

Worth every penny.


You have calculate it on read based on the user's state at that time.

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


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 :)


Thank you, I put a lot of time into the design and CSS.


Does this book have much relevance for someone already working in an existing engine like Unity?


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.


> This book makes me want to write my own engine

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.


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.


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!


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.


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.


Have you heard of the Nu game engine[1]? It is a FRP-based game engine for F#.

[1] https://github.com/bryanedds/Nu


I have. It seems pretty neat, but .NET is not for me.


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!


This book is pure gold. I recommend this to any programmer!


I love this book and will not only will it help you for game development, but all software engineering in general. Highly recommended.


It's a good book, but it contains lines of code that appeal to the subconscious like:

int destY = unit->y() - 1;


Do you have any recommendations for books about Game Architecture?


Game Engine Architecture is a great overview and on it’s third edition.


First version of this book was an immense help for me early in my career.


I used the second edition extensively on my masters. Truly a gem!





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: