Confusion on what is considered "bad design"

I am currently doing research on how I should be structuring the modules in my game, but have hit a mental block along the way.

I have learned of this concept of loading modules without requiring them within each other. As I have heard that this practice is considered “bad design”.

I am confused on what exactly is considered “bad design” in coding structures and would like to know if there is some kind of definitive source to aid me in developing good designs for my frameworks. I realize that the name of the game is conserving memory, but where do I find such practices to even begin tackling this monster.

I realize this is a very broad question, but this is where I currently stand on my coding adventure. Confused without any real idea of what kind of questions to ask.

Any tips would be very appreciated.

1 Like

I don’t think its bad design, I just think its inconvenient.

Having a module that is required, and having assets from that module that are needed for another module needs a loader style that has a priority system. (I had to make one)

If your planning to do a module based system where one script loads all the modules at once, I would prefer figuring out how you will do your priority system. If you don’t have a specific priority, it could result in errors upon loading.

2 Likes

Just don’t overthink it too much. Do what is best for you and the game you are creating.

1 Like

I do have a priority in mind when it comes to the execution of my modules. Though If people see a need to not require modules within modules then I want to at least try to investigate on what exactly led developers to this conclusion. But if it really doesn’t matter then ill take your word for it. :smile: Though while that question is answered I still would like to know if there is some kind of coding standard that I am blind to. This was just a standalone example.

I think this was a bad category to pose this question. Would there be any way to change the category of this post?

Thank you, ill try to keep this in mind going forward!

Yeah this is a complex topic mostly just due to how broad design in general is. When it comes to design though usually the biggest focus is maintainability so long as your code is performant enough to actually work. And with maintainability being the main focus there tends to be some general guidelines that can help with that, but they aren’t hard rules.

Basically it all tends to boil down to keeping your code modular and decoupled. Basically to the extent reasonable your code when it updates should not be breaking other code and updates should just slot right in. This tends to lead to things like the single responsibility principle and encapsulation as overall “rules”.

I’m not quite sure what you mean by this tbh

But I suspect from my fuzzy understanding this has to do with encapsulation. Generally scripts should only be requiring data they need directly and shouldn’t require all the data. Not because they can’t, but because it makes it more clear exactly what their intended scope is which helps with maintaining it and reducing unwanted side effects (don’t want a script in the middle of your game to be editing a random variable from a seemingly unconnected script for example so it’s best just not to give it that ability at all). As stated though, this isn’t a hard rule and you would find well structured code all over the place that doesn’t strictly follow that.

2 Likes

hiding skip cutscene button in settings

1 Like

I see. This definitely gives me a direction to look in and I greatly appreciate that! Also for the confusion the best I can provide is a code example of what I am speaking of

for _,Modulescript in pairs(ModulesFolder:GetChildren()) do
    local Module=require(Modulescript)
    setmetatable(Module,{__index=Modules})

    Modules[Modulescript.Name]=Module
end

vs

local module1 = require(smth.module1)
local module2= require(smth.module2)
local module3 = require(smth.module3)
etc...

I am more comfortable with the latter, but I am afraid of developing bad practices so I try to use the former.

for gods sake don’t use pairs. its just faster and better to use in, using pairs is already a bad design

Honestly the second one is better imo. The only real time the first one is better that I can think of is if you are creating a loader that needs to handle all of them. Like if you were trying to copy something like game:GetService(“blahblah”) for example. Otherwise directly loading them into a variable like the second one is pretty standard since most scripts only load a couple anyways.

1 Like

Interesting. Though I am glad that there is no major issues with using the good ol require method! Thank you again for your two cents. Ill keep this in mind going forward.

1 Like

Everyone has a different structure depending on their own preferences and the game they are developing, and all of them consider their structure to be the best for numerous subjective reasons. So I would not listen too much to them if I were you, otherwise, you will be endlessly confused about how you should structure your code based on their opinions.

Therefore, you should always use your own structure, the one with which you feel the most comfortable and familiar, regardless of other developers’ opinions. After all, you (and your teammates) are the only ones who script the game. Additionally, you will naturally evolve your own structure over time as you gain more experience and identify what might be wrong with it or what needs to be improved, all while keeping it as you like.

Regarding modules, there are many different ways to use them, and none of them are ‘bad’. You can use them as simple storage, for an OOP system, or even like a normal script if you want to. As long as you end up coding your game correctly in a way that you feel is best to you and your game, it’s fine.

1 Like

Thanks for the aspiring words! It seems that this is the general consensus so I think I will focus on my own style from now on. Thank you for your time!

1 Like

I have not read your initial post, but I do seem to see what the discussion is leaning towards. Yes, design can be largely subjective, but there is an objective component to bad design. Bad design is often brought about by design choices that inhibit core principles of your project’s progression and stability. These largely include scalability, modularity, and maintainability. There officiated design patterns that can help you make better choices, most of which the YouTuber CodeAesthetic puts very well. His content covers these issues and tools in a very intuitive and friendly manner

2 Likes