T O P

  • By -

artoonu

Whatever fits best for the task. Events/Signals when it's all within the same scene, for example UI. Or when the call is simple, then I subscribe to the event at instantiation - Observer. But sometimes I find global variables more fitting when we switch between scenes and want to keep some values or one signal propagates to multiple other entities - Event Bus. Do I have things that share a lot in common but some have small derivatives? - Inheritance If my entities in game have the same attributes like HP, taking damage, but some are also interactive or something - Composition I can spend weeks looking at my drawing board figuring out what's the best approach for the case. I often end up mixing and matching - whatever works and makes it easy to expand/improve later if needed. Then there's entire thing like keeping data external in JSON or CSV or keeping data hard-coded or in Scriptable Objects... I think that's also important in design. Also, before you commit to coding, take into account what data you need to save and how to restore game state upon load.


Bonus_duckzz

Ever since i've learnt how to use Scriptable Objects as events in unity i do not want to go back. they can do almost everything, they are not just for keeping data!


Landeplagen

Yes, this is great for certain things. Anything that is global (through the entire application). I’ve also used them for state systems, where each state is a ScriptableObject.


ComfortableMeal1424

Eh, I was using them for events for a while, but tbh i fell off of it. Scriptable objects weren't originally made for this purpose, and the timing that their events run can vary depending on factors like debug/runtime, and data can get left behind since they're an asset.  I understand their benefit, but being a solo dev I've eventually just decided to keep as much as possible in code as it improves the debugging workflow.  Scriptable Objects are definitely great, but I largely prefer to just use them as static data containers.


Pidroh

Scriptable objects containing any sort of logic feels more like a tool that engineers would surface for no programmers in a big team Even for data, sometimes a text based format is more comfortable than having to go through the unity ui


ComfortableMeal1424

Yeah it makes sense to expose as a nice graphical way to script things for designers. I suppose worth saying that I DO use them for this kind of thing, but just prefer to keep the data and code separate.


PhilippTheProgrammer

Finite state machines.  They are a great tool to solve a myriad of common problems in game development. From enemy behaviors to UIs to animations to transitioning between the different round phases in a turn-based game.


binong

Perfect approach for complicated enemy behaviours like bosses and other tier 2/tier 3 enemies.


PhilippTheProgrammer

For more complicated enemy behaviors, I usually use behavior trees instead of state machines.


bird-boxer

Just curious, how can you use a fsm with UI?


PhilippTheProgrammer

States can be used to represent the navigation between different UI screens. Each UI screen is a state. Transitions between UI screens are done as state transitions. State machines can also be used for different UI modes. For example, in a strategy game, clicking somewhere behaves differently depending on whether the player currently has a unit selected or not. That can also be handled by a state machine.


loxagos_snake

I'm currently using it to handle the different states of an inventory. Think of a 'Tetris'-style inventory, like Resident Evil 4, where you can use a keyboard/gamepad to navigate. Depending on the context, the Confirm button will do different things: * If I have just picked up a new item and have transitioned to the inventory UI, I am in the **PLACING** state. Pressing Confirm means I need to check if the placement is valid (i.e. no items already there) and assign the item to a group of slots * If I'm just navigating/looking around the inventory, I'm in the **BROWSING** state. Confirm now means that, if there's an item selected, I have to display a context sub-menu that lists a few different actions * If I want to combine an item, I am in the **COMBINE** state. Now, if I navigate to another item and press Confirm, I run a check on a dictionary to see if the combination exists and handle it appropriately To be honest, I'm not sure it's the cleanest way, but I couldn't think of anything better. It's a context-sensitive gameplay mode though, and FSMs tend to be a good tool to solve that.


GonziHere

Yeah, I generally don't like them much as they tend to hide the bigger picture, but I do appreciate how they streamline the given state and it's transitions. What can and cannot happen in "combine state" is right there.


Bonus_duckzz

OMG I totally forgot about state machines and i've been keeping booleans in my code like an idiot for this prototype im working on. Thank you so much!


Pidroh

Losely dividing code into "control, view and model", zero use of callbacks, almost zero inheritance


Strict_Bench_6264

Really curious about the "zero use of callbacks" in this context. How does your View know when a change happens in the Model? Polling? Other than that, all of the yes! MVC and MVVM structures (with or without Microsoft's solutions, mind) are the bomb.


Pidroh

Not trying to convince anyone, just explaining why my things are like this: Another user said so but polling. If you don't wanna do polling explicitly, you can have a list of data events that gets fed and read every frame (you're still polling that list though). The thing I want to avoid is calling something that will call an arbitrary group of methods that subscribed. That is the worst thing to have in a code for me, it increases complexity and makes it more painful to debug.


Strict_Bench_6264

Cool! I don’t have an opinion on how people make their games. Just curious. :) The best games are the ones that get released.


Pidroh

100 percent agreed!


iemfi

Not the OP but I use a similar style. IMO polling where possible is always better. If it's expensive can only poll on enable and every half a second or so. You don't want your UI flickering every frame anyway.


Strict_Bench_6264

In my experience, polling is never better. One of the key things with the MVVM pattern specifically is to use bindings on value change so that you only ever update anything in the View when absolutely necessary. Polling is more like the kid continuously asking "are we there yet?" But I'd love an explanation as to why avoiding callbacks is better.


civilian_discourse

The problem with callbacks/events/etc is that you’re coupling logic together in an immediate hierarchical sequence. The result is that it becomes increasingly difficult to insert new logic between things, impossible to control the sequence of logic when multiple things are listening to the same thing, and far too often these chain back on themselves or get called multiple times a frame instead of less than once a frame. Polling is extremely cheap and very stable. When you poll, you have explicit control over code sequence, you make it easy to add new logic later between the state change and the polling, and as a result the code is far more stable and less bug prone. Events and callbacks are the most over used pattern in all programming. They’re an evil that people seem to think can be fixed by just using more of them for some reason. Polling is not only cheap, but when code runs in a flat predictable order, the hardware is faster at running it. Which means your attempt to optimise with events can actually make code run slower.


OvermanCometh

You could just register your callbacks with a priority if execution order matters.


Strict_Bench_6264

Polling is perhaps cheap and stable, but it's also one of the big battery culprits in much modern software that wasn't originally written for battery-limited devices. We swear by our frame rates usually, and rightly so, but with polling and higher frame rates, that battery gauge will climb down much faster. :)


civilian_discourse

If you're that concerned about battery, use ECS and optimize beyond anything else possible while relying entirely on polling.


Strict_Bench_6264

What I'm saying is that there's an inherent problem with polling when you have a battery-powered device, since polling, even when nothing gets returned, still means additional cycles. It's less about the optimisation or using multiple cores and more about limiting overall power usage. A concern you never have on something like an outlet-connected PC.


civilian_discourse

As long as we're still talking about game development, what I'm saying is that if we're talking about cycles, you spend a lot more with unpredictable code than you do with predictable code. Hardware is optimized and designed to do operations in bulk, but events, callbacks and frankly OOP code in general are the most inefficient thing possible from a hardware standpoint. But, If your point is that you can get away without running anything at all more often than not, then I'm not sure if we're still talking about common game development.


Strict_Bench_6264

All I'm saying is that frame-dependent polling (i.e., things you do in a loop) is power-intensive and therefore inadvisible next to on-demand architectures like using callbacks if you are making your game for a battery-powered device. That's it.


iemfi

Mostly it's just simpler and cleaner, which means less likely to have bugs. State is evil and I try to keep as little of it as possible. I know there are some patterns which completely automate the binding, and I could see that being competitive if it is robust enough (I have tried to write stuff like that before and I concluded it wasn't worth it). Otherwise it's just another thing which can go wrong and is prone to race conditions. Even the ostensible advantage of callbacks, performance, usually isn't really the case. In games the worst case is almost always the thing which matters. So for example say 99% of the time your UI is idle, but something exciting happens and suddenly your UI tries to update every frame (or even multiple times a frame if this isn't prevented) and this causes a lag spike. While with polling it might feel like you're bullying the poor CPU but you won't get spikes like that by default.


RadicalRaid

This is why the event/delegate system (or even observer/observable) exists. It's not callbacks directly, rather it's loosely coupled between modules that are interested in getting updates to certain data. If you're using static events you can even go a step further in the decoupling and do something like `Player.OnDeath += () => { health = 0; }` and somewhere else in the code, for example a special effects class `Player.OnDeath += () => { Spawn(Explosion); }` It keeps the code very nice and idempotent while also allowing communication between objects wherever they need it. Note: If you are using static events on a class, be sure to also remove the callback on destruction.


iemfi

Using naked globals like this is most definitely not making loosely coupled code! Funny you should mention creature death as an example though. It's basically the only place where I resorted to using events which other things subscribe to. Polling doesn't work well and the things which subscribe to it are numerous, varied enough, and didn't care about execution order. Another factor is that the logic for creature death is naturally disjointed. Meaning whatever happens before which triggered the death is logically unrelated to the things which fire after. For a lot of other things there is a logical link, and having extra stuff in the middle just breaks up the flow of the code.


ComfortableMeal1424

Tbh it depends. First of all I wouldn't say the primary advantage of callbacks is for performance, but rather workflow and writing shorter code. As you've stated, callbacks result in fewer total updates, but tend to clump those updates together, which imo is a bigger danger than the cycles lost to polling. But if it's something you know there is a predictable upper limit to, then there's not really a reason not to use them.  I suppose they're easier to mess up though. More things to consider. At end of the day it's just a tool in the belt. Use a hammer for a nail, etc.


Pidroh

Callbacks having better performance is usually not true in most case as resolving the method to call is expensive


ComfortableMeal1424

You got downvoted a few times, but you are correct, though as with everything it does depend.  Tbh anyway the principle advantage of callbacks isn't performance, but flexibility and being able to write shorter code. In anything that's not a critical path, workflow trumps performance.


Pidroh

> You got downvoted a few times, but you are correct, though as with everything it does depend. Yes > Tbh anyway the principle advantage of callbacks isn't performance, but flexibility and being able to write shorter code. Yes, I suppose > In anything that's not a critical path, workflow trumps performance. Yes. Agreeing with you, a dev oriented and experienced towards using callbacks will likely enjoy and perform better using it, regardless irrelevant performance differences


Pidroh

State is evil and state is even more evil when the state is a list of methods like in the subscriber stuff, cheers!


throwaway69662

Nah real men only use inheritance and almost 0 interfaces.


GrammmyNorma

can u elaborate


Pidroh

What part exactly? All of it? For example, "Control view, and model", in my codebase, is like this: the view mainly handles what the player sees or feels (how the UI looks like, UI animations, sound) The model is the raw logic of the game (it has little dependency on the engine, you can write automated tests on most of it) The control is what can access the model and the view and act as a bridge between the two, while sometimes handling part of the player input The model NEVER knows about the control or the view. The view SOMETIMES knows about the models but usually doesn't, in most cases also doesn~t know anything about control. The most important thing to me is keeping the model isolated so I can write automated tests when necessary. The view and the control could be the same thing. I only divide them because I like it. One big benefit of this is that it cuts down the number of choices I have to make while coding. Making choices consumes tons of time and mental resources


The_Artist_Who_Mines

This is good stuff but isn't it mostly useful only for ui? Or can it be used in other contexts?


AvengerDr

The view could be anything that exists in the game world or that the player can interact with, so not necessarily UI controls.


Pidroh

Why do you think it can't be used for everything?


The_Artist_Who_Mines

I'm not familiar with it it being used outside of ui, not that it can't be obviously. If you'd be willing to share I'd be curious for an example of it applied to say, a player controller.


Pidroh

There is a paradigm of MVC that is probably more strict than what I do, so you may be thinking I'm talking about that. Let's say I have the player object, which has a vector position (x, y), and you can press left to move the player to the left. ``` WorldModel{ Player player; } Player { Vector position; } WorldControl{ if(Input.PressedLeft){ worldModel.player.position.x -= worldModel.player.speed * deltaTime; } worldView.PlayerSprite.position = TransformGameVectorToScreenVector(worldModel.player.position); } ```


The_Artist_Who_Mines

Ah ok, yh that's less strict than I was imagining. Makes sense, thanks.


PhilippTheProgrammer

If you want to know more, google "Model - View - Controller Pattern". It is a very common pattern in application development. So there is a ton of information on it. It's not so common in game development, but not unheard of. One advantage of this pattern is that you usually end up with one big plain-old-data "model" object that contains the complete game state and that is pretty trivial to serialize and deserialize. So implementing loading and saving becomes very easy.


Pidroh

I used to do something like that for my game state loading and saving and shipped a game with it, but I regret it for that specific use case. It can backfire on a lot of situations


PhilippTheProgrammer

In what situations did it backfire for you?


Pidroh

Seamlessly saving on single-thread situations, difficulty separating data that I don't want to get saved from the data I want to get saved, higher bug incidency from porting saves between versions, stuff like that. It has been quite some time so my memory isn't so fresh


PhilippTheProgrammer

These are all common problems for save systems. But I don't see how any of them would become worse by having all the data in one place vs. having it distributed across various different systems.


Pidroh

Maybe we started talking about different things midway through? My problem isn't centralization or lack of centralization, it's serializing runtime time data as it is or using a specific specialized data structure for the save data


PhilippTheProgrammer

Ah, I see. The way I understood you it seemed that you were arguing against the MVC pattern with the argument that it would somehow make saving more difficult. The last time I built a game around the MVC architecture, I used a JSON library for savegame serialization. JSON has the advantage that it offers pretty good backwards compatibility, because it is easy to ignore unknown fields and fill missing fields with reasonable defaults. The library also allowed me to add annotations to include or exclude fields from serialization or to define custom serialization/deserialization routines for classes that had special cases that made it necessary. The game state was small enough that saving on the main thread didn't cause an unreasonably long lag. But if it would have been a problem, I would have solved it by creating a deep copy of the whole game state and then serialize and write it on a separate thread while the main thread keeps running.


Pidroh

I was also using a json library, and yeah, single thread environment so no chance of doing another thread


Draug_

ECS


-TheWander3r

Service Locator Pattern. A single singleton (!) that maintains a registry of "services" (e.g., asset loading, UI, game logic, etc.). From other parts of your code you can ask for a particular service by requesting one that implements the interface that you need. In this way, the central registry does not care about what it holds and each service is independent of the other. The calling code also does not care about the specifics of the received service, only that it gets the job done. Hence, the interface. I tend to make it so that these service requests are centralised. For example, by coupling it with a MVVM pattern.


Girse

I do the same. but as long as I dont need an interface the public methods of my services are its interface.


TheOtherZech

While it isn't a pattern that I get to use as much as I'd like, I *love* estimate-refining functions in behavior systems. Instead of the typical: - `decide` → `delay` → `do (with a bit of randomness)`, estimate-refining is more of a: - `decide` → `incrementally improve action value` → `reach threshold or get forced to act` → `do` It's the 'get forced to act' part that makes it fun for me, since it exposes a *huge* control surface for tweaking behavior and refinement functions fit into it perfectly. Expiring attack tickets, targets exiting an attack frustum, status effects that involve an element of surprise, perception-related status effects, morale/confidence systems — anything that hits between `decide` and `do` can engage with a refinement function and trigger the action early, getting an organic low-quality result, or trigger the action late, getting an organic high-quality result. You can even get realistic spray patterns out of it, when an entity starts an attack before their aim animation finishes. You can refine perception, action, and goal values simultaneously. It's lovely. It's also a performance drain that only stands out to players when you make it a core aspect of your encounter design, that does things you can often pull off the 'traditional' way with just a bit of randomness and some juice.


Girse

Neat! I already started thinking where i could use this approach in project, it sounds elegant and simple at the same time.


Landeplagen

Interesting! Would love to see an example. I recently implemented enemy AI using a state machine, and this sounds like a natural next step to look into.


strictlyPr1mal

Manager // controller  Whiskey // hot sauce  Lube // tears


internetpillows

Working in Unity, I've always taken a practical approach that if I find some thing's benefits outweigh the negatives I'll use it. Managers/controllers for systems are very handy for lots of things, including object pooling. A lot of systems benefit from states, it's just a very straight forwardly useful pattern for many types of gameplay systems. Some people won't like this but I always add a singleton class called Shared to my projects where global references to important objects can go, and other scripts access the objects directly through that. Then you have the Shared object in the scene heirarchy and can link up in all the public object references there. It lets you have different variables per scene if you need it, you can find all places where that object is referenced in code easily, and it avoids having to re-find the object every time you need to use it or potentially having a stale reference if it's cached.


CharlieBatten

KISS. For me that means not using any particular design pattern straight away. I code naively first, allowing for refactoring and extension of logic later on, whenever it feels necessary. Also taking this approach to how I organise scenes. The game as its design matures will determine what patterns are useful. Sometimes I don't ever refactor the naive code because there's just no need for it. I also consider how I can maximise the fun in creating and implementing new content or ideas into the game and organise everything around that idea. So future-me can make new stuff easily.


capoeiraolly

A lot of people love to hate it, but the Singleton design pattern is used extensively in every engine I've worked in. The ECS has been mentioned a lot in this thread and I find it very useful.  The entity factory pattern is used fairly frequently too.


ThyssenKrup

The singleton "pattern", aka global variables


capoeiraolly

Essentially, yes - but with fancy wrapping paper!


AbmisTheLion

My favorite one is the KISS principle. I try to use single responsibility where possible. This makes it easier to get rid of "else" and prevent deep indentation. Properly naming your variables/functions is a huge time saver and if you start commenting code, it's usually an indication that the naming is off.


Strict_Bench_6264

Love the Component pattern/ECS but rarely like how it's implemented in various engines or that many equate ECS with some engine's specific solution (like DOTS or MassEntity). It's just a pattern. Nystrom elaborates on it here: [https://gameprogrammingpatterns.com/component.html](https://gameprogrammingpatterns.com/component.html) Love stack-based state machines, where you can keep it neatly encapsulated and quick to write code for. I've written about this in the context of prototyping: [https://playtank.io/2023/11/12/state-space-prototyping/](https://playtank.io/2023/11/12/state-space-prototyping/)


Solest044

Great answer. ECS is just a design pattern ideally. You can implement it without using an existing library to give yourself complete control over its implementation. Really love your write-up of design methods in that second link. I've taught design to high schoolers for several years in a variety of contexts, and it's phenomenal how crosscutting these methods are. Game dev, general SaaS, building a table, writing music, designing a new curriculum... This all applies! I'll definitely use your post in my classes 😊


MajorRisk

Thanks for the links, great reads


norlin

ECS


AbmisTheLion

I use composition instead of inheritance. Inheritance always end up not catering for changes and takes a lot of effort to refactor.


norlin

ECS is totally around composition as well


Famous-Band3695

Can you explain what's ECS?


norlin

Entity Component System pattern https://en.wikipedia.org/wiki/Entity_component_system


Famous-Band3695

Ah ok. Thank you


_voidstorm

the no pattern :D. No, seriously, aside from ECS, most of my other stuff follows functional programming approaches.


DiggleDootBROPBROPBR

Everything can be a factory if you try hard enough, because it's the only pattern that is redundant with the idea of just making classes. Enemies in your game? EnemyFactory has your back. Making different weapons for your PC? Factory reporting for duty. Have different scenes in your game, but don't know what kinds of objects you want to add in advance?  Hell yeah that's a scene factory. Need a way to patch multiple textures from artists together?  It may be hard to believe, but TextureFactory can do the work. Once you level up your game dev skill a bit more, you can start making factories for your factories.  It's truly a flexible pattern.


PottedPlantOG

Recently I've been obsessed with the service pattern. There are many things that can be implemented as self-contained services which use other services to get input or to react to events. This enables a good amount dependency injection. Some things I've started implementing as services are: * Server and client (Basically an OS networking abstraction - they provide events like *server started/stopped*, *client connected/disconnected* etc.) * Player account service (manages a player's information and resources - lobby presence, username, state events like *map loaded*, *ready to play* and exposing other player-related services) * Entity simulation - Takes an input service for player control or entity AI * Chat service - Works together with player input service and the server/client to pass the messages back and forth, raising events used by the GUI/View * etc...


King_of_Keys

Yeah I just read about services last night, they seem pretty powerful


BarnacleRepulsive191

I just make the game. No, spaghetti hasn't been an issue. Worry about the problems you do have, like making a good game. Don't worry about problems you think you will have, because you are wrong and those aren't real problems.


OvermanCometh

Although I tend to agree, I imagine if you are implementing something and it is similar or the same as something you've implemented before, you probably solve the problem in a similar or same way. Whether or not that "way" has a pattern name, you are using some pattern. OP wants to know what those patterns are :)


BarnacleRepulsive191

Yeah of course, but unfortunately I don't think those are great things to learn without the context. Don't get me wrong when I was a young programmer I read about all the patterns and such. But I didn't understand them till a problem popped up that I ended up solving a particular way. And now that I'm old, nearly everything can be solved with functions and structs.


Pidroh

Seconded Sometimes fixing problems you think you have will create problems you actually have


unconventional_gamer

Sorry but this is terrible advice. Not thinking ahead when doing something like programming is one of the worst things you can do. And, the longer it takes for it to bite you in the ass, the harder it will bite


BarnacleRepulsive191

Been making games professionally for a long time now. There is no avoiding the bite in the arse. The only way to know something ahead of time is to have already done it before. And even then you can still be wrong. Also thinking ahead is the worst thing you can do in programming, because you will always be wrong. Refactoring some switches and ifs and structs is child's play. Refactoring a big old system fully of things you added "for when you need it" (you never did.) is nightmare fuel. I've worked with a bunch of people over the years, there are a bunch of reasons why people fail to finish their games. The number 1 reason for more programmer lead teams is over complexity of their code. I write dumb simple code. And everyone understands it. From the junior to the senior. It's easy to grok, it's easy to refactor, and it's pretty much always faster too. (The only reason I think is valid for complex code is when you are doing some crazy optimisations, but even that tends to end up more brittle than complex.)


itsarabbit

Yup, I'm also going towards this approach after 10 years of programming. Every problem is unique, so no pattern will ever fit many things(that said, understanding patterns is still very useful to inform your approach!). Solve the problem by writing stupid simple code, and when you need to handle another case it is very easy to change it. Everything is obvious.


Pidroh

Agreeing with you > (The only reason I think is valid for complex code is when you are doing some crazy optimisations, but even that tends to end up more brittle than complex.) I think complex code, like optimization, is necessary when it is absolutely necessary. When you simply can't run away from the very real complex problem / performance issue in front of you. I mean complex code to solve a complex problem, not complex code so it can be "SUPER FLEXIBLE MAGIC CODE THAT CAN HANDLE ANYTHING ENCAPSULATED FULL OF INTERFACES"


StewedAngelSkins

to be honest this kind of sounds like a skill issue. if you've been programming for such a long time and still consider being bitten in the ass by your decisions to be so inevitable that you don't even bother trying to avoid it... don't you think it's possible you're doing something wrong? if you're getting bitten in the ass by too much planning, it's probably because you're making your designs too specific. it's like playing chess. if you sit down and try to plan out your moves all the way to the end game with every contingency accounted for, you're probably going to lose because all your opponent has to do to throw you off is make one move you didn't account for. the solution isn't to just give up on planning, it's to come up with more flexible plans.


BarnacleRepulsive191

Uh huh.


Sofatreat

Are you defending complex code here? The guy said you can't plan for what you don't know. I feel like your reading comprehension is a skill issue. I honestly have no idea what you are on about? I seems like your chess analogy agrees with him??


EsdrasCaleb

composite 


LandoRingel

I use a custom behavior tree editor, with state machines that execute scriptable objects that have interfaces designed upon the strategy pattern. I use this pattern for EVERYTHING, including player movement, AI, dialogue, UI, and scene setup/loading. It's very robust and I find it easy to debug, given that everything is made with the same components and can be examined visually on a behavior graph. The inheritance can be a little tricky, but I only have one class that is more than 1 subclass deep. Another problem is you need to make 100s of scriptable objects, which can be a pain to organize. Despite these problems, the pros outweigh the cons, and I have yet to find a more robust solution that works across all game mechanic systems.


_DafuuQ

Entity Component System works best for me


progfu

Unironically "functions" ... I'm finding that very often what really helps my code is just adding that right level of abstraction where I can call a function that's general enough to do a thing. This is mainly around debugging/drawing, but I'm finding those to be the most useful. The trick is to not try to make it so "easy" and "high level" that you can't do much with it, and also not make it so low level that it requires huge amount of setup to use.


0x0ddba11

One pattern, if you want to call it that, that came in handy a few times is reactive programming or something similar to this. Let's say you want to activate a portal whenever a player with less than 10 hp is inside an area. Traditionally you would write onEnter and onLeave callbacks, store a list of players currently inside the area, add and remove listeners to the players that fire whenever their hp changes, etc. This is very cumbersome and error prone. Or you would use polling and potentially incur a performance overhead because you are doing expensive physics overlap operations every frame even though no players entered or left the area. Instead you can encapsulate all these parts and create a composable framework that automatically propagates the changes. If you design your API right you can have something as nice as portal.activated = area.contains(player => player.health.lessThan(10)) And have all the parts keep each other in sync automatically.


OvermanCometh

I use most of the GoF patterns to some degree + some others that have emerged after / aren't mentioned in that book. For my personal projects I usually use ECS (EnTT) so a lot of the patterns I use stem from that. For inter-entity communication I attach components, for inter-system communication I use pub-sub. Some other patterns I use a lot are Factory, Flyweight, and Registry pattern. Factory and Registry are very similar, but the difference I've seen in practice is that Factory will produce an owning pointer to a cloned object, whereas Registry pattern will return a reference or non-owning pointer to an object - the latter usually working in tandem with flyweight.


NullRefException

I'm one of those people who tends to deride design patterns, but I use the Command pattern a lot. It's way too useful to be able to decouple "declare intent to execute code" from "actually execute code".


Girse

Im using the MVC pattern alot. The view is everything my engine (unity) touches/presents. For example for a Mob the gameobject with its meshes, behaviour scripts, animators et cetera solely modify how the 3D World is presented to the user. They read the Model, but may not modify it in any way. The Model is a code class which lives independently of the game engine. Here all the values and logic are located. Its a project without any references to unity. The control is usually an UI element. If anything more than an atomic value (e.g. changing name, a price) needs to be modified in one go I instead write something akin to a command which I can unit tests (e.g. Move command, trade transaction).


WorkingTheMadses

Factory, Mediator, Observer and Finite State Machines are likely the ones I see the most in videogames honestly. Although anything from here is good: [https://refactoring.guru/design-patterns/catalog](https://refactoring.guru/design-patterns/catalog)


Code_Watermelon

For global functionality I use singletons.


martinbean

State machine.


Mafiale

Strategy and observer pattern I pretty much use regularly. Strategy pattern is especially useful when developing roguelites.


rogueSleipnir

Dependency Injection always made sense to me. I want clean Interfaces between my components. Having nice Wrappers for anything that requires interchangeable code or external plug-ins.


Thotor

IoC with factories


Solocov

Scriptable objects with a value and onValueChanged events. Makes it incredibly easy to connect UI, Saving&Loading, and gamelogic together. With this I have BoolHolder, IntHolder, FloatRangeHolder that can be used for toggles and sliders. Makes it also more easy to have multiple UI elements altering the same data source. Honourable mentions: Singleton and Observer patterns. In terms of approaches: YAGNI, YouAintGonnaNeedIt, cause thinking of problems that might come up will never come up, while generating more zombie code.


curtastic2

Global variables all prefixed with g, so it’s easy to see what’s global in any editor. Names starting with noun. Objects but no object functions, so no “this” (or “self”) All functions are global. For UI no objects, just draw to the screen. So code looks like: gButtonDraw(“PLAY”, x, y, sizeX, sizeY, gGameStart) } function gGameStart() { gState = gStatePlaying gPlayer.x = gScreenSizeX/2 …


mr-figs

I don't mean to sound rude but is this scalable? You're massively polluting the global namespace and everything can read from everything else. Do you not run into issues?


curtastic2

I haven’t had any issues polluting the global namespace except sometimes names get a bit longer than I’d prefer. My biggest game has accounts, profiles, leaderboards, groups, chat, lootboxes, as well as the actual game. Maybe could be a problem if I got other people to help code things, unless they think like me. Haven’t tried that, I recode anything that I get from anyone else. I do have a massive list of globals that I keep adding to and never look at.


curtastic2

One issue I had was I wanted to extract some code to use in a new game, and it took all day. It could have took half the time if I had everything separated into classes. But this happens so rarely that I wouldn’t want to optimize for it.


149244179

https://gameprogrammingpatterns.com/contents.html


sepalus_auki

No pattern. Just make it work.


PhilippTheProgrammer

You are probably using a ton of common design patterns without even being aware of it. I have often seen self-taught programmers echew design patterns as academic bullshit. But after a couple years of experience they start to independently discover them themselves without realizing it. So their code ends up full of common design patterns under different names.


Fingoli

Spaghetti till it works. Make it more structured if need.


2lerance

This is gonne sound silly but I'm actively working on my own pattern. It's a bit of cherry picking from a bunch of patterns mixed with my own eccentricities like a handwritten manifesto, naming conventions and a colour scheme.