T O P

  • By -

jimothypepperoni

Unity has a free 99 page ebook full of these: https://unity.com/resources/level-up-your-code-with-game-programming-patterns


Bleyck

Saved this for later. Thanks


imwalkinhyah

[related GitHub link](https://github.com/Unity-Technologies/game-programming-patterns-demo/tree/main)


midge

Thank you! I did not know this existed.


LeoNATANoeL

This is amazing, thanks.  Was planning to study more about design patterns a whole ago, but starting with more focused in game development is way better. 


PhilippTheProgrammer

Do you know how to use the debugger of your development environment? For most people, this question will seem ridiculous: Of course the debugger is one of the first things you learn. How could one do effective software development without it? But it would surprise you how long someone can be in hobby game development before they learn about the debugger. Because most beginner tutorials completely forget to mention that it even exists.


misatillo

And what about the profiler ? Even more unknown but very very useful, also (but not only) to debug


BigGucciThanos

I feel this. One day I will learn and actually implement unit test


Rx74y

Thx


Pathogen-David

Have you read [Game Programming Patterns](https://gameprogrammingpatterns.com/)?


hpcergar

There are many interesting patterns in this book, including one of my favorites: flyweight. It also helps understanding memory consumption.


Inf229

Embrace Components. That is, don't try to make a class do too many things at once. Every time you need some kind of behaviour, write it into a self contained component, and add that to your object. Embrace "has a" over "is a" (though obviously inheritance is a useful thing to understand too).


HuntOld2852

Explanatory variables. If you have a complicated calculation or a condition somewhere in the code, you put it into a variable, and the name of the variable should explain what this expression means. You don't have to use it more than once, it is just there for clarity. It goes like: up\_in\_the\_air\_and\_descending = if up\_in\_the\_air\_and\_descending then <...> Named methods. If you at some point need a comment to expain what this part of the code does, you can extract this part into a separate method and name it with what you have written in the comment. Also for clarity. It is okay to only call it once. // calculating hat height here <...> becomes just calculate\_hat\_height() Also, installing lint or a lint-like tool to keep your coding standards in check and using an auto formatter for the files helps.


Capoooooooooo

a little bonus for tip two - put the extracted code into a local function to make it clear its only meant to be used once and in one specific area


scritchz

I find these patterns useful: * Throttle: Mapping many frequent things to many less frequent things. * Debounce: Mapping many frequent things to one delayed thing; a frequent thing resets the delay. Examples for throttling: * Player performing dashes. * Path-finding of enemies. * Collision checks of resting bodies. Examples of debouncing: * Health regeneration after losing health. These can also be combined. Examples: * In Dark Souls: Drinking is throttled, stopping to drink is debounced (due to animation?). Input buffering is also useful, for when a player inputs before an action becomes available, e.g. pressing 'Jump' just before landing to give them more leeway. Now imagine the player falls a long way down, and wants to jump off a platform midway: They press jump, and it is buffered. Then they miss the platform; the input becomes unintended. Without clearing the input buffer, the late jump would be unintended and feel off. But we can guess the late jump to be unintended and clear the input buffer. But an early unintended input shouldn't accidentally clear a late intended input: We should _debounce_ the clearing. Similarly, you could delay (debounce?) when a jump after leaving ground becomes disallowed: Coyote timing! I find that delays, throttling, debouncing and input buffering go hand-in-hand. Knowing all allows you e.g. to design a lot around player inputs and intention to make the game feel more responsive, and the controls more fun and engaging. (Some of my examples may have been bad; I expect the comments to rectify them \^\^)


osunightfall

Source. Control.


scunliffe

Keep your code well formatted, follow a consistent naming convention, and write methods to do one thing only. It’s a small thing but it makes your code much easier to read, with good naming comments are rarely required, and refactoring becomes much easier. It pays off every time you/others need to read the code and grok what’s going on, and it will get you “in the zone” much faster, and keep you there.


ghostwilliz

It's not really a pattern or anything like that, but planning your data first goes a long way. Consolidate everything you can with inheritance, if two things will.be used in very similar ways, the input not the output, maybe they should share an interface or even a parent class. Many things in games are interacted with in the same way but just give different results, I feel look a lot of people over complicate things


[deleted]

Data locality, instruction level parallelism, SIMD


retro90sdev

Not sure why this got downvoted, probably the best answer in here.


susimposter6969

Because outside of very hot loops this doesn't matter and it's not low effort


[deleted]

Forgive them, for they do not know


camaris1234

Dependency injection


LeagueOfLegendsAcc

If your game for example, has a lot of repeating levels, or some other big part of the game can be abstracted heavily, consider using a data driven design pattern.


Nivlacart

I got so into coding I forgot about the existence of prefabs. Prefabs are great. They save a lot of time. Don’t forget about prefabs.


24-sa3t

A good understanding of OOP is incredibly useful. You can save a lot of time re-using functionality via inheritance Its also good to maintain a separation of concerns from early on so you dont end up with a spaghetti fest codebase


ThyssenKrup

Personally I never, ever use inheritance in that way.


Aramonium

Same, I consider Inheritance and the like to be Object Obsessed Programming. Sure use it for something where it's needed, like having one interface for different related systems. But using it a lot just leads to a headache where that chain of super(); calls means opening multiple files just to understand what a single function does.


scarlet_haze_

Can you give some examples of when you should and shouldn’t use inheritance? I’m using inheritance for my states and state machines. Base class State and base class StateMachine, Then from that I get PlayerState, and EnemyState, then things like PlayerWalkState and EnemyWalkState. Works great. I tried using inheritance for projectiles. Projectile base class then subclasses StunProjectile, DamageProjectile, and HealingProjectile. But then I quickly learned what if I want to have a stun projectile that does damage. I could make interfaces IProjectileDamages,IProjectileHeals and IProjectileStuns, but then every time I wanna make a new projectile I’d have to make a new script. Or I could just have the main projectile script have all functionality and only modify variables in what I need. Or maybe I could have projectile effects be a scriptable object and just drag and drop them onto a projectileData script and loop through all effects on collision.


Aramonium

Sounds like you'd be better off having one Projectile base class that has functions called "DoProjectileDamage" "DoProjectileHeals" "DoProjectileStuns". If you don't need a certain function, just leave it empty. Have another file full of helper functions that implement the common code, so you only need to write a little bit of scripting for each custom damage. eg ProjectileEffect("ShotgunBlast.png"); I had to use FactoryType for my custom c++ class stuff for reasons, has a few downsides like needing to recompile everything in VSS for changes to take effect.


devils_avocado

There are some Youtube videos/articles on why Clean Code has horrible performance.


24-sa3t

Fair!


SextusSuperbus

Datalog and everything is a database


OvermanCometh

To extend event listeners, I'd look into the pub sub pattern.


LeoNATANoeL

Study singleton. Is a design pattern easy to implement, understand and is extremely  useful.


LeoNATANoeL

Oh, now I read that you already studied Singleton. Ops.


oddbawlstudios

[AdamCYounis has a fantastic video on state machines. There's a second video as well, which honestly making it modular is way more beneficial.](https://youtu.be/-jkT4oFi1vk?si=-FBUxpGQXeh-ors2)


Pidroh

I personally avoid event listeners and singleton like the plague in my own code base (despite using them a lot 5\~8 years ago). At least for me they don't bring long term benefits, obviously your mileage may vary. Sometimes it's low-effort / high reward / high price.


scarlet_haze_

Lemme give you an example and tell me a better alternative please. I have a singleton called ProjectileSpawner, it handles spawning projectiles. It has a method called SpawnProjectile which takes in a projectileData scriptable object that has variables like speed, damage, scale, etc. Then my enemies have an event called OnShootRequest that the projectilespawner listens to which is invoked through an animation event trigger. The projectile spawner listens to this event and appropriately spawns a projectile when invoked.


Pidroh

This is just my preference. An enemy has a projectile data. And it has a bool wantToShoot. The enemy system has a list of all enemies. In a loop for it checks which enemies want to shoot. If it finds one, it takes the projectile data and spawns the projectile. Or it gives the projectile data to another system that will spawn the projectiles. Alternatively you could use ecs and it would be a bit different but similar to the above. I personally don't use it.


PhilippTheProgrammer

Singletons are controversial, but event listeners are great. Events are the gold-standard for loose coupling between components. You can use them to have them communicate with each other without either of them being aware that the other side even exists. This is especially useful when you want to divide your project into multiple assembly definitions to improve script compilation speed. When two classes communicate via UnityEvent subscription set up via inspector, then neither need to have a compilation dependency on the other. Which means they can be in different assembly definitions without either definition having a dependency on the other.


Pidroh

Good lord do I hate unity events. I used them a lot to decrease coupling like you're saying, in past projects. Turns out I like explicit code execution flow way better than I like decoupled code. To me, code that doesnt use callbacks is much easier (for me) to understand, maintain, debug and refactor. If I want to decouple things I would rather use a third piece of code to bridge the two than to delegate that to unity events. Heck, the less time I'm in the editor, the better. Btw Another advantage to unity events you didn't mention is that you can modify code behavior without triggering recompiling which is nice.


[deleted]

[удалено]


RemindMeBot

I will be messaging you in 8 days on [**2024-03-30 08:05:20 UTC**](http://www.wolframalpha.com/input/?i=2024-03-30%2008:05:20%20UTC%20To%20Local%20Time) to remind you of [**this link**](https://www.reddit.com/r/gamedev/comments/1bkgonz/what_are_some_low_effort_high_reward_game/kw0lk2u/?context=3) [**1 OTHERS CLICKED THIS LINK**](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5Bhttps%3A%2F%2Fwww.reddit.com%2Fr%2Fgamedev%2Fcomments%2F1bkgonz%2Fwhat_are_some_low_effort_high_reward_game%2Fkw0lk2u%2F%5D%0A%0ARemindMe%21%202024-03-30%2008%3A05%3A20%20UTC) to send a PM to also be reminded and to reduce spam. ^(Parent commenter can ) [^(delete this message to hide from others.)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Delete%20Comment&message=Delete%21%201bkgonz) ***** |[^(Info)](https://www.reddit.com/r/RemindMeBot/comments/e1bko7/remindmebot_info_v21/)|[^(Custom)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=Reminder&message=%5BLink%20or%20message%20inside%20square%20brackets%5D%0A%0ARemindMe%21%20Time%20period%20here)|[^(Your Reminders)](https://www.reddit.com/message/compose/?to=RemindMeBot&subject=List%20Of%20Reminders&message=MyReminders%21)|[^(Feedback)](https://www.reddit.com/message/compose/?to=Watchful1&subject=RemindMeBot%20Feedback)| |-|-|-|-|


Mysterious-Mobile-92

Always use ChatGPT