In the beginning, i usually create just one component like MainController for nearly all of the game mechanic. After the core gameplay is functioning and need to extend more mechanic/content, i try to separate functions from that MainController into several components. It feels organic but also wasting lots of workload.
I only made small games so far, but I usually have PlayerController, GameManager, MainMenu, and the rest like enemies, or items. I try to keep scripts clean and compact, and hate it when one class goes over 1000 lines, so I separate it, but only if it wonāt make it more complicated. I find it hard to navigate after 600 regardless of how clean I made it.
These things can vary greatly depending on the project.
I just counted how many lines of code Iāve written for this current (PC) game (not counting assets with scripts from the store, just my own code) and Iām at over 25,000 lines so far. Some of my classes have up to 5,000 lines. The game is a work in progress so itās only going to get larger. Just counted the lines from my previous game and it was almost 65,000.
No matter how hard I try, I just canāt seem to reel it in. Almost everything is commented, as well, and I do my best not to spaghetti-fy things too much. Then again, looking at the line count from some big PC games and apps, I guess Iām no where near them. Whew.
Good god!
I tend to not comment my code cause it make it longer, and sometimes more cluttered. But I do add a keyword here and there, just to know whats up. But as far as assets go, I commented almost every line.
If it makes you feel any better Pond Wars weighs in at a massive 982 lines of code. The longest script in the game is a third party tool at 131 lines. Most of its scripts sit in the 50-60 line range.
Its not how big your code is, but how well you use it.
It definitely is difficult to anticipate exactly what file hierarchy youāll need. It takes practice, and you get better at it over time. But programming organically isnāt the āwrongā way to program. Especially when the design changes so frequently, as in my last job. Thatās why *refactoring *is such an important part of development. If you feel that file sizes are getting larger, or you are starting to have difficulty understanding your code because too much of it is doing too many things, by all means, take the time to refactor it into smaller classes or components. Itās called technical debt. Itās natural.
Anyone tried using Resharper with Unity? I use it daily in non-Unity projects, but havenāt tried it on Unity code yet⦠If it works, that could be a huge timesaver (seriously recommended if you spend a lot of time coding)
I donāt see any problem with putting everything in one place, then moving later. Do whatever youāre most comfortable with. Itās similar to my workflow but I make sure I refactor quite often - as soon as the current task Iām working on is done.
Sometimes Iām rushed and forget to move something though - having someone else find that code a year later can be embarrassing
I feel ya. I contracted for an insurance company whose codebase was I believe around 100 Gigs. Trying to download it all at once from source control would crash at some point in the middle so new devs had to pull it down in chunks.
Our current project hasnāt reached anything near 7 million lines yet but probably will eventually. We are cranking away at it full time but it isnāt a single application. Itās all SOA with a service bus, decision engine and workflow underneath that weāre building out.
As to the OPās concern, I agree⦠split it out from the beginning. If nothing else, try to think about what the logical components of the game are. Is there AI? Interaction? Spawning? Separate them at least into the major systems and it makes it easier to split those into smaller subsystems or parts later because they are all related.
I recently read this article. I thought it was an amazing article that relates to this thread. It talks about the beauty of code, specifically Quake 3ās source. It talks about why this code is good and lists some good coding practices that was used. I highly recommend it.
BTW even John Carmack left a comment in the comment section!
Although there are some nice tidbits many of the things listed in that article are formatting choices, which some will debate till the end of time (most of these can be automated by an IDE anyway).
My take: do what works for you, and your project (i.e. you might use different approaches for different projects based on). More importantly donāt be afraid to analyse, learn, and change your approach. Unfortunately this often gets harder as you gain more experience.
I agree with most of the points they have there⦠except for same line brackets. Only for an if statement that consists of several else if will I put same line brackets.
On topic though, I believe smaller modular code chunks are better.
The benefit mostly comes when you are working on your next game and decide you need a script that does [this], and you have one already made in another project, that you can drag and drop in because you wrote it in a generic loosely-coupled -to-the-project way.
But⦠do what you want. Unless youāre working with other devs, who cares what coding standards you use
I agree with the modular approach, but also believe that you shouldnāt make anything loosely-coupled unless either: it makes sense to do so (in terms of existing architecture) or you already know you are going to reuse it.
Architecture changes over time - youāll never know up front how your application should be structured so just do what feels natural.
Loose-coupling for the sake of loose-coupling has never worked out well for me - and itās easy to fall into that trap where you start seeing tightly-coupled components everywhere.
Off topic: did a line count of the (non-unity) C# project weāve been working on for 6 years now - around 2 million, including unit tests, and I have frequent Visual Studio crashes. Canāt imagine working a project 3-4x that size - Iāll never complain about the size of the project again
How about focusing on small, reusable abstractions and make your objects a combination of reusable components.
Like, a script that moves things and has a speed and direction property.
Then depending on the object, you can attach a component that sets the direction of the object based on logic, like one that aims at a transform. Then you can use it any time you need anything to point at anything.
And so on. Reduce, re-use, recycle.
Youāre trying to not repeat the same code anywhere.
Hereās whatās cool about having pieces that arenāt connected to all the other pieces, who mind their own business⦠you donāt have to āstructureā this massive program like an Egyptian pyramid builder⦠you just let the simulation run itās course.
If your code is all in one file you have a lot to learn. I recommend reading the pragmatic programmer and hope that something sticks. Thatās what helped me stop doing exactly what youāre describing.
Modular code and loose coupling, while not mutually exclusive are really different things. If you make modular code, then directly reference it, then itās coupled. Using interfaces you can loosen that coupling and IoC / DI you can decouple completely, but being modular does not always equal loosely coupled. Iād agree with you that decoupling can be overkill, especially in a component based game project but itās still important to be as modular as you need to be. Making your components reusable / interchangeable is just one benefit. Maintenance is in my mind the biggest. If you need to modify the behavior of a specific subsystem itās much easier to do if it is isolated in its own āmoduleā, i.e. not intermingled like spaghetti with your other code.
Also, if you really try to put your entire logic into one class file⦠well you can but youāll have performance headaches during development. Eventually the file will get so large that the IDE will have trouble processing it.