Dealing with my messy code

Started by
13 comments, last by Oberon_Command 5 years, 9 months ago

Hello everyone, so I had this problem since the time I started programming. And the problem is that my code is a complete mess. The further into the project I get, the messier it becomes. The main problem I'm facing is coupling. It seems that everything I write becomes coupled with other classes, which makes adding new features very cumbersome. At most places in my code, nothing just makes sense. I know there's a better way doing it, but I just don't know how to do it. I've seen other people's code (for example ThinMatrix's on YouTube) and their code just seems so effortlessly programmed and easy to understand, while mine looks like a pile of mom's spaghetti. All I want to learn is how to properly structure my code, which patterns to use and when.

Apart from Game Programming Patterns, which other books could you recommend? Maybe any open-source (preferably java) games to learn from? I'm asking because after working on a project for 1 or 2 months it gets so messy that it's hard to even remember where in the code I need to make changes to implement a new feature or fix an old one. Also, I know this might sound stupid, but I keep thinking that maybe I'm just not that mentally capable. Share your stories, maybe you had same problem as I do and managed to overcome it? If so, how?

 

Anyways, thanks in advance for your replies

Advertisement

Don't be discouraged, we all have this problem.

 

I usually plan a bit of my game and start coding.

This leads to a lot of spaghetti code and me getting frustrated after a while which then leads to me dropping the project.

I can give you several ideas which you could use to improve your mess:

 

1. try to plan your code just like your game itself. Plan the folder structure and classes and how they interact.

2. try to implement dependency injection if you use a lot of communicating objects. A container that can help with the handling of classes might make your code easier to sort.

3. try to use manager classes which handle the communication instead of the classes themself.

4. try to implement systems and entities instead of functions and classes. This means you build entities that can interact with systems and not classes that call other classes. This would help to logically connect your code instead of creating technical dependencies

 

In case of books I can not help you since I am not reading many books (internet ftw :P) but I know that there are a lot of good resources so maybe others can help with that.

There are two kinds of programmers...... those that write messy code, and those that lie...... Everybody's code is messy, and it gets messier as you go.  You can do your best planning, and STILL it ends up being messy.  My best advice is when you get to some reasonable level of functionality, go back and clean it up. It's much easier to do this once you have something working, because you can see where the issues are.  You may even have to do this more than once during the life of a project. It's called refactoring.

Just pust aside short sessions to do nothing but tidy your code and If you do it regularly the skill will come to you.  Start with indenting, commenting, renaming for more meaningful variables names and make your code easier for you to read.

When I did this, I liked to pretend I was an assistant to myself and setting up for the next big coding session where I did nothing but create new code.  Eventually, I met myself in the middle and now mostly tidy as I go.  Yet, I did like that approach and found my bugs were greatly reduced and the code naturally became more reusable as I had given myself the time to spot opportunities.

Languages; C, Java. Platforms: Android, Oculus Go, ZX Spectrum, Megadrive.

Website: Mega-Gen Garage

Compartmentalize. I "try" to write small independent structures and place them in individual files. These do specific jobs and have no direct communication with others. This ends up with some redundant code (trade-off). I have a controlling structure that ties all the others together and passes any required data between. This way I always have a single structure to look at when I need to make changes. And for the most part any changes of a structure have no effect on any other (except the controller).

This is how I make my insane thoughts seem sane.....

9 hours ago, Hawkblood said:

Compartmentalize. I "try" to write small independent structures and place them in individual files.

That's a neat kind of development.

Bigger structures can be used as libraries that should be kept in a different repository.

Those libraries can be reused later and if you have a setting where using libraries is the standard way, you can easily add external libraries to your project.

Learning how to refactor to reduce the mess is a key skill. I hope it goes without saying, but two important tools to enable confident refactoring is to use version control and to have a fast unit test suite.

Of course, the hard part is knowing what to do that will reduce the mess!

I find that books are a difficult medium through which to learn this, as most of the challenges come from larger codebases than most books are willing to address, and structural problems that are hard to really explain without working knowledge of the code in question.

Personally, one of the places I learned the most was right here on gamedev.net. When I was getting started I found there were several members who introduced me to new ways of thinking about programming. I don't know if a new person today would have the same experience, as the world of programming Q&A is likely irrevocably different now that forums like here compete with Stack Overflow.

Exposure to different ways of writing code will be good for you. However, there is a danger here. If you read the source for frameworks, game engines and some libraries, you might see all sorts of abstraction and generic code and you might think that this is good design. When I was starting out, I was in awe of all the complex code you could write and I strove to replicate that in a codebase that didn't need any of it. Since then, in my experience, I've found that good library design is quite different from good application design. Each abstraction you introduce must deliver a big benefit, as done poorly they can make the code much less clear.

Another challenge is how much to design up front.

My approach is to write small programs that work and grow them into larger programs, rather than think too much about the design up front. This requires occasional mass refactorings once the program reaches a critical level of complexity where the current overall design starts to feel like it is getting in the way. If you've not done this many times, it can seem scary, but with version control and a battery of tests there is little to worry about. This will allow you try out alternative designs and see if they help.

Writing tests can help influence the design of the real code (you may wish to read about "Test Driven Development" for details). Even if you don't go as far as TDD, writing unit tests for your code will force to you interact with your code in small pieces, which should highlight problematic dependencies.

Code that has lots of dependencies is almost universally considered to be more difficult to work with than code that has few or no such dependencies. An ideal to aim for is to have independent "modules" that have minimal knowledge of one another.

For example, one game idea that I have takes place with ships moving between planets in a solar system. Assuming there is no existing library that covers my needs, I could start by writing a gravity based physics simulation module that supports massive objects (stars, planets, moons) and negligible objects (space ships, missiles, space stations, etc) and that will handle the movement and prediction of these objects.

The main thing to remember is that this is a practical skill, you'll get better with experience. Don't compare yourself with people who have likely been programming for a long time, they weren't so good when they were starting out! Rather take inspiration from where they got to, and try use that to motivate yourself to hone your craft.

Good luck!

Start by writing unit tests.  I mean: write the tests first, then write your code (TDD).

You'll find that in order to make your code unit-testable, you need it organized.

You will find that having plenty of unit tests makes it easier to refactor your code as you organize it, or reorganize it, but the biggest benefit of TDD is you end up doing a certain amount of design up front instead of just jumping in to coding, and the sequela of design is organization.

Then, move on to BDD, which helps you find and organize your unit tests and helps you avoid the trap of writing tests to the implementation instead of the interface.

Stephen M. Webb
Professional Free Software Developer

On 6/8/2018 at 4:37 PM, Bregma said:

Start by writing unit tests.  I mean: write the tests first, then write your code (TDD).

You'll find that in order to make your code unit-testable, you need it organized.

Although I like the idea of TDD, I would rather recommend taking a look at what the framework presents as "best practice".

If you are using a framework that is very hard to test, you should not use 99% of your time trying to get your tests to run at all.

I think it is better to plan your game structure before starting to code and try to use code structures and concepts that align more with how the framework is supposed to be used.

I am currently using Phaser to write games in Javascript which is reeeeaaaallly unfriendly in terms of testing.

Don't get me wrong, I agree with having organized code and spending more time to implement a good structure than patching something presentable together which breaks apart after the first change (and change is coming for every project!).

 

When I am more proficient and plan my next project, I will try to implement some unittests.

Until then I did a lot of documentation and structuring for my current project which hopefully is enough to hold it together for a while ^^.

 

Can you even write decent unittests for Unity or similar UI based frameworks?

TDD..... I've been doing that the whole time without knowing it was a thing. BDD sounds more like using scripting to finish development after you have proven your code using TDD....?

This topic is closed to new replies.

Advertisement