Structuring Code for Large Project

Hi everyone,

I feel that I have reached a point where I am an “intermediate” coder, but I struggle to have clean, polished and well organised code when the projects scale up.

I am watching tutorials and studying others’ work in order for me to understand better how I can learn to structure my code better. I understand what these people do, but I struggle to replicate it myself… and this is because I am still not as experienced and because I cannot foresee what changes and additions I will make to the project later in the future.

Does anyone have some tips on what I could read, watch, practice on in order to improve at this?

Thanks in advance!

You should ask yourself if all “these people” end with the same structure. If not this should be a hint that there is not one right way to do it, but everyone of “those people” has found a way that works for them. So you should also find a way that works for you and not try to mimic other people. Because what works for them does not necessarily also work for you.
I see it that all things (in general) have advantages and disadvantages. Different people weigh them differently based on their prior experience. So its good to look what other people do to get an impression of the pros and cons. But you should not follow them slavishly.

As actual advise I suggest reading Clean Code by Robert Martin if you haven’t done already.

I am studying the workflow of the new ECS / DOTS implementation. It seems that you approach it from a different angle and that many problems of OOP just vanish with that different mindset. If you are also interested in this or the principles behind data oriented design which can also be applied without ECS in “normal” OOP coding read this free introduction.

If you are already watching and reading guides on how to do this but struggle to replicate it because of unforseen changes, then you are probably ‘just’ missing practise. Plan it out as best as you can and learn from what didnt work out well. Improve that in the next project.

As a rule of thumb (which you probably read about): keep things modular.
This goes for both, the project hierarchy as well as the class hierarchy. You’ll have some code for, say, level generation. Great, put it all into some folder. Everything related goes into there, and of course potentially subfolders with subfolders and so on. Got enemies? Great, another folder.
In your class hierarchy try to minimize code redundancy. You dont want to write things twice. If you have two enemies they will share a lot of code. Create an abstract base class and use inheritance and composition to define enemies. Now, if you need to rework the walking function for enemies, you can do it in one place. Changes to one enemy should not affect another one. Changing or replacing all enemies, should not affect, say, level generation.
You will have and need certain dependencies between modules, which is handled through some interface. For example, the level generation knows that some form of enemies exist, and uses that to call enemy.Spawn(). It doesnt care about what happens inside of that, so the module ‘enemy’ is threated like a black box. Each module is. This makes them rather easily exchangable, as long as the interface is kept in tact. An interface should never change (removing pieces that are being used), but can increase in size when new functionality is added. This basically implies that you can always add more, or rework existing pieces, but should try not to remove things unless necessary.
Now if you need to remove or rework parts of your project, you just replace one module with another. Are not happy about some part of your level generation? Rewrite that part. Or throw out the entire folder and start over level generation from scratch. You will still be able to access the interface of other modules to make enemies spawn and so on. While some scenes may break, the project hierarchy itself would not.

One last note: global variables are a nightmare for clean project hierarchies. Only use them when absolutely necessary. They cause tons of cross-references that easily end up breaking things. While useful for some cases, overusing them is one of the best ways to absolutely mess up your project when scaling up.

Thanks, I’ll take a look at the book! I heard other programmers mention it if I remember correctly.

Thanks for the in-depth insight!