#Questions on Code Architecture

1 messages · Page 1 of 1 (latest)

crisp trail
#

Heyas! I've been using Unity for a little while now, and I started being experienced enough to notice flaws in the architecture itself of code. I feel like I kind of developed an OCD for perfectly decoupled, all-generic, SOLID code, that I become somewhat embittered when I see any dependency in a class. I've searched everywhere on the web and nothing was fitting, so I'm starting to wander if what I'm looking for even exists.

I know architecture patterns depend on the project's size, but I'd like to find one that suits me best that I could use even for smaller projects, just to develop good practices. Do tell me if that's an error though.

What would be all the things I can do to get an extremely decoupled code ? I want to be able to have "conversations" between systems (UI, gameplay,...) with basically no dependency directly.
Also, what would be the ""best"" game flow pattern for this?

I've started working on a new project recently, and used a finite state machine for the flow. However, I started running into issues with states depending on UI stuff, but none of the solutions I've found were really fitting (right now I pass the State Machine to the states' Enter and Exit methods, and in this machine lies a reference to a "GameContext" class holding a bunch of different references - but still this doesn't really suit me because if exposes a bunch of different stuff that is all needed but not all needed by a single state). How would I go about that?
I'm mainly looking for more general solutions, or good rules of thumb.

Thank you for reading and for answering if you do, I hope it's not too long.

white terrace
#

honestly, the simplest way to keep stuff decoupled is to just not couple things together in the first place. Make everything private by default, only expose variables that absolutely must be shared.

If you have a player class with a bunch of stuff in it, designed in a way where 100% of what it contains is private, youve intentionally stopped the player class from being at risk to have a bunch of other stuff rely on accessing what it has, which could lead to the player class turning into dependancy spaghetti

#

then if your UI code absolutely must know the players health value, make it have a public get, private set so you can read the value, but nothing outside the player can do anything to its data

#

walling as much stuff off from the rest of your code, is something that involves a bit more planning and thought to make it work correctly, but its one of the best ways to keep your project in order

unique badger
#

I know architecture patterns depend on the project's size
This is a pretty important point, really. There's a thing about super decoupled, flexible and elegant code that even your grandchildren can use - they won't! But you will. And you'll have to deal with the extra complexity that comes from the decoupling. When you get a bug, instead of jumping between 2-3 classes, you suddenly need to go through 6 levels of abstraction, 4 events, and a whatever.

My point is - be careful about not overdoing it. My general recommendation is to go with a simple solution and only expand it if things start being... problematic/uncomfotable/unruly. (That's something that kinda comes with experience - noticing when something starts to be bad and needs to be refactored.)

And another point - code can't be fully decoupled. Someone somewhere needs to connect things, so the question is who and on what level.
You could use a global event bus. Everyone can throw events through it. Components that fire the events don't need to know who listens. Listeners don't need to know who provides the data - only the type of data. Cool, but that's a magical hidden dependency.
You could make many low level systems that don't know about each other, but then the data would need to be passed between them by higher level components that know about the lower level ones.

So, I guess the question is: what does this class (or a set of classes that form a feature) need to know about? if I use any form of decoupling, what do I actually gain?

#

I should probably also say something positive about decoupling 😂

Decoupled code to a reasonable level can be easier to read, refactor, extend. I tend to make systems as stand alone as possible and connect them in higher-level components/systems. But that's useful for a system - something that's multiple classes/interfaces, defines a pattern for doing something... in other words - is big enough that I want to keep it separate and manageable.

crisp trail
crisp trail
# unique badger > I know architecture patterns depend on the project's size This is a pretty imp...

Yeah that's definitely something I realized. I think it's almost a bad habit I have being annoyed at each dependency I see but, I mean, there's gotta be one at some point lol

I think my main problem is indeed knowing where to put this connection. Many solutions I found were also talking about event buses so I might try that. But that doesn't seem to fix the issue of getting "any" data anywhere (e.g game config values as "internal settings")

Thank you for the advice. I will try things out but I really think I just need to fix my very strong will of wanting to make everything "flexible and elegant" as you said... It might be hindering at some point indeed

crude loom
shell cliff
#

With UI separation in particular It's helped me to imagine if I needed to develop like a NPC/AI character playing the game the same way. So like in a Pokemon battle I obviously don't want/need the npc to "press" those buttons so the buttons just need to middleman firing certain functions and events etc.

unique badger
marsh warren
crisp trail
crisp trail
#

I'll definitely try to stop trying to overengineer