I have bad code

4.5

How do you guys get clean, manageable code that can also do whatever you want? Because I want to write code that can do anything I want it to do without relying on tutorials. And I don’t like the Godot docs too much because most of the time it doesn’t make sense.

1 Like

Nobody writes the code for their game perfectly on the first try. Create something, test it, rewrite it into better code, test again, rewrite once more, and so on. Once you have a larger part finished, you’ll realize that something in the foundation isn’t optimal or doesn’t fully match your vision. Refactor the code, test it, rewrite it again. Working in iterations may seem complicated, but it’s a proven way to reach your goal.

6 Likes

Hi,

You might not like my answer, but what you’re looking for is called “experience” :smile:
There is no answer that we can provide here that will make you able to write perfect code on your next project (I wish there was), as it takes time, pratice, trial and error, etc.


Do not look for perfect code, as it simply does not exist. You have to commit yourself to some code architecture to do some progress on your project, and later on, you may realize that your decisions may have some flaws, or that your architecture is not working. At that point, what matters is how you handle the situation: you can either delete all of your code and start it all over, or, you can take some time to think about your code, trying to understand why it does not work, and refactor it, or start it all over, but this time with insight.

Keep in mind that refactoring code is normal, you just cannot avoid it. I’ve been working as a programmer for 5 years and refactoring code is a large part of my tasks. Iterating on code is what’s expected from game developers; it’s litterally a part of the job.
Cool thing is, the more you’ll work on different games over the years, the better your codes will be and the less painful your refactoring will be.

Imagine you’re doing a pixel art illustration. You cannot paint each pixel one by one at get a nice result, you need to start with a sketch, try to apply some basic colors, cleanup the line, and then maybe you’ll rollback a bit because something’s off and you want to draw it again, etc. until you reach a nice final result.


Although experience is key, there are some existing stuff that can provide some help regarding writing a clean code.

First thing that comes to my mind is design patterns. The idea of design patterns is that, for a given type of problem, there’s a re-usable solution, applicable to any langage/game engine. For instance, one of the most used pattern in games - I think - is the Singleton pattern, which you may know.
I’ve read that book like 2 years ago: https://gameprogrammingpatterns.com/ and I liked it, I think it does a good job at explaining some simple patterns.
There are lots of resources online for design patterns, I don’t know them all, but you can look for the ones you find helpful.

Also, you can develop some good code habits, simple things, but that can make a difference: do not duplicate code but refactor it inside functions, try to apply some of the SOLID principles, etc.


Anyway, I wish there was a magical solution to your problem, but really it’s just about practicing and iterating. You can also share some of your codes here once you feel you’re struggling too much, so that people can try to see why your architecture is bad and tell you how to improve it.

7 Likes

Aw..

But should I stop using tutorials since my game is just gonna be a game filled with tutorial code rather than my own code?

And is renaming your variables refactoring? I heard that starting a variable with an underscore (_) means that variable only has to be there and not anywhere else. If so, where can I find the right ways to name my vars, consts, etc?

I gotta say if your code works and u can read it later ,that means you are on right path.
writing clean code is just nothing .

1 Like

Using tutorials is fine as long as you understand the code you’re getting from it.

Copying and pasting code you don’t understand can be okay if you sure you will never ever change that code. It works, and it will always work, case closed. Problem is: you never know what code you’re going to change or not, so you have to be careful about writing code that you understand and you that can read months/years later to iterate on.

It can be a part of refactoring, yes. Refactoring usually refers to changing the code structure, not just variable names, but it’s a part of a whole.

You’re looking for naming conventions. There’s a Godot doc about that here.
You can also use your own conventions, the most important thing being that you always follow your rules in all cases, whatever they are. That will make the code readable, more enjoyable to work with, which means it will be easier to refactor it and iterate on it.
Naming is not the most important thing compared to architecture, but it definitely is important.

3 Likes

Another good rule of thumb for writing better code is to make sure each function or script focuses on just one clear purpose. (Single responsibility)

For example, instead of writing a single function that both calculates a score and updates the display, you should separate them out into a function that handles the math and another that takes care of showing the result, which makes your code easier to understand, test, and maintain.

You should be able to describe what a script does with a simple one line description. So this script updates the UI. This script manages user input. This script generates enemies. etc etc.

Hope that helps. Don’t optimise too early though, and when prototyping messy “that will do for now” code is fine too.

4 Likes

Hold on… don’t optimise too early?

Wait so do I just write ugly messy code for all the things the player can do, and then optimise it when the player code is fully completed? Or optimise it when the code is halfway? (Not sure if i’m using the word optimise properly.)

I believe there are two clear stages in game dev. Prototyping and Production.

When prototyping, yes, messy quick “that will do” code is fine. The chances are you will recode it, dump it or alter it significantly later anyway when you ask “what if my player could do this?”, or discover flying is much more fun than jumping… or whatever.

Never the less, you still code it ‘clean enough’ after all you have to come back to it. As @sixrobin said, experience helps here. I know that I will need a ‘enemy_manager’, ‘environment_manager’ and a ‘player_manager’ anyway so I start even prototyping with these and similar things from the start.

Then as your prototype starts getting more complex, refactoring starts.

Then, when you have it all decided, production starts, and you start coding it all again but this time as clean as possible. Or perhaps your prototype starts slowing down and FPS gets too low, so you think “how can I optimise this to speed up my game”?

But, when I have an idea, the first thing I do is make a prototype as quickly as possible. Squares and circles, chasing the Godot icon around. Is it fun? Good. Does it matter if my code is clunky and messy at this point? No.

Hope that helps. Don’t spend 2 weeks making a script super slick and beautifully coded and professionally optimised ready for release when you don’t even know if your game is fun or not or even what your basic game mechanics are going to be.

3 Likes

It usually is like that. I’m also quiet fresh in this and what I understand so far is: start with something messy, but readable. As long as I can understand what I did in a week or two, it’s fine. Then, after I got something set up, i look at it, find dozens of “mistakes” I made and change many lines of code to work better.

Better can be: faster, easier to understand, cleaner (as mentioned above, separate things a function/object does into single, granular things) or more flexible. The last one is something that started being more important to me just a few weeks ago.

Think for example of controls. You want them to be there in the first place. Then you want to tweak then to better do what you want. Then you want to clean them up and make them easier to work with in the long run (i.e. instead of using numbers for some parameters, give make them variables, link them etc.). And then, make your controls more flexible to be able to use some aspects for mouse/keyboard and some for Controller input.

3 Likes

@ximossi
That is a good example. Player movement takes ages to get ‘just right’. But getting it ‘just right’ for a prototype is pointless. Camera motion is another good example I think.

No, you don’t write messy ugly code ever. But there is a difference between “I know I will have to extract this to a separate script later” and writing spaghetti code that even you cannot decipher just a few weeks later.

Personally my early code is littered with comments like:

# TODO  this should really be in a settings file to alter from level to level

# TODO camera will later be controlled by the user

# TODO just generating 5 enemies for now, need to control this in level settings
3 Likes

How do I know if i’m out of that prototype stage though? What if i’m still in it? Or what if i’m already out of it?

And if I do have messy ugly code (which I think I do.) Then do I rewrite it? And make it messy instead of messy and ugly?

(Sorry for many questions! I’m a dumb beginner.)

First of all, there are no rules. If it works it works. But there is good practice and there is lots of good advice from people that have been coding for many years, but nothing is written in stone.

IMHO, you’re out of the prototype stage when your core gameplay mechanics feel solid and fun, and you’ve tested the basic features enough to know what works and what doesn’t. At this point, the game starts to shape up beyond just proving an idea, it’s ready for polishing, adding content, and refining the player experience. If you’re still experimenting heavily or making big changes then you might still be prototyping.

Some people would also say ‘when your play testers enjoy the game’. Getting play testers on prototypes is a good idea.

But, refactoring code is really something you do all the time. It is just part of coding life. IMHO it is a fun part of coding. It’s not “how do I make this work” at the refactoring stage, it’s “how do I do this better”.

For instance, between these posts, I have been refactoring my camera manager so that the camera it controls now has all the camera settings in it. The intention is later to have the camera manager switch between cameras, but for now I only have one camera. I might make the one camera have different states like “following_player”, but I have this idea for an intro where I want to take complete control of the camera, and for the death sequences, and for the in-base mode, so I am toying with having seperate cameras for them and having the camera manager switch between them. This is because I know that camera controllers can become quite complex from my previous game and I am trying to refactor the code so that ‘potential mess’ is alleviated.

However for now, during this prototype, one camera is fine, and the camera manager is currently just setting that cameras target positions and zooms, while the camera takes care of the zooming and repositioning. I know that later I will have to refactor these again, but for now it is working fine and is a step towards the final more complex set up.

I love refactoring code. I used to hate it and thought “I am going to write perfect code immediately” but this is unreasonable.

Just start making your game. When a script starts looking messy or it is not absolutely obvious what a function does or is for, just bear in mind the single responsibility. You will get the hang of it and in time you will get faster and faster at it too.

Good luck and I hope you enjoy your coding as much as I do.

We are all dumb beginners. On the mountain of coding excellence most of us are still at base camp. Watching or listening to the real pros discuss things is amazing, but down here we are all just beginners really.

5 Likes

I very much agree with that statement. Personally, I think coding shares quiet some similarities with carpentry and architecture, professions which put lots of emphasis on hands-on experience as well.

Some people write their program twice, so the second time can benefit from the experience learned from the first time. And a few like myself have so many failed projects, we are practically writing the “same” project multiple times. The architecture does improve a lot, though.

Just remember finishing projects are important too and it also comes with experience.
Well, I am working on that one too. :stuck_out_tongue:

5 Likes

You should make sure that you thoroughly understand the code that you look at. This will require perseverence, especially when you see a new technique that you have never come across before. This can be infuriat-ing, but if patience prevails, you will be the victor.

  • commodore 64 programmers reference guide 1982. Its still true today.
2 Likes

What does "clean’ actually mean here?

That will have to change, better sooner than later :wink:

In general, code is not important, beyond obvious basic style guide stuff. What makes a program easy or hard to follow/understand is the architecture i.e. how data structures and their interconnectivity is designed.

3 Likes

I don’t get clean code. I just write what works and fix it if it messes with me later.

2 Likes

That’s actually how things get done. People obsessing over “clean” code often tend to stuck inside analysis-paralysis loops. Besides, “clean” is never well defined. It can mean different things to different people.

1 Like

Yeah, to me ‘clean’ generally means like easy to read and uses all the latest practices, etc. but it’s difficult keeping up to date, and also if a script works, why risk breaking it more just to be slightly more readable.

I think for many people “clean” is equivalent to UncleBob’s notion of “clean” - i.e. extremely object oriented and chopped up into as small as possible functions. There’s false assumption that such code is readable and easy to follow solely because there’s no much code inside each function. Imo following the execution where every call “encapsulates” a recursive chain of 10 more nested calls - is a nightmare. It’s bad for performance as well.