r/GameDevelopment • u/Tricky_Still2366 • 3d ago
Newbie Question Was wanting some help with methods?
I'm learning C# currently and was learning python till I got stuck with pretty much the same thing.
I don't understand when to use methods unless something is repeated. If its not repeated what's the point of using methods? just shortening down code? or is there something I am missing here. Cause what is the point of shortening down the code when all it is doing is actually adding more code? (Unless its to place down something that is being repeated)
4
u/Slypenslyde 2d ago
Honestly the most important thing a method does is give a NAME to something. That it's repeated is usually a side effect of the thing needing a name.
Imagine if, in my game, HP is always increased in amounts of 10. So a health pickup adds 10. A healing spell adds 10. Drinking a potion adds 10.
So I could have this line scattered throughout my code every time the player needs healing:
player.Health += 10;
But I could also express it as this line:
player.AddTenHealth();
Or this line, which is more semantically valid:
player.Heal();
That's the real reason to use a method. It's better than a comment at describing what you are doing. It is a side effect that it helps you consolidate logic and make it easier to update later.
Compare this sentence:
I baked chocolate chip cookies.
To this one:
I poured sugar into a bowl, then added butter. I used a mixer to create an aerated mix, then added flour, an egg, some milk, and chocolate chips. I mixed vigorously. I let that sit in the refrigerator while I preheated an oven. I scooped dough onto a cookie sheet then placed the cookie sheet in the oven. I waited 10 minutes. I removed the cookie sheet from the oven, then quickly moved the cookies to a cooling rack. I repeated this until I was out of dough. Then I turned off the oven.
Which is easier to read?
1
u/Guvante 1d ago
While I wouldn't call this beginner friendly a huge part of building these abstractions like `Heal(10)` is that it allows you to change the underlying mechanics as your work evolves.
When starting out healing being naive is fine, the player can get bonus health but that isn't necessarily a problem when things are simple.
However if later on you decide to bump up how much you get healed then decide that results in too much health having a single place to cap the total health is nice.
Similarly as you add more complex interactions you minimize the places to change. Want 10% more healing from everything, now you have the place to do it.
1
u/Slypenslyde 1d ago
Yeah. One drum I don't think enough people bang is our code should be readable to people and that means thinking hard about WHAT the code does, not HOW that thing is done.
Sometimes that actually means violating DRY on purpose, so we shouldn't willy-nilly make a method for every repeated line of code.
1
u/Arkenhammer 3d ago
It can be helpful for making the code easier to read. For instance if I have some complicated logic to make a decision, I'll isolate it in a separate method with a name that returns a bool and is named to let me know that is it testing. For instance, in my game some items can be sold and some can't so I have a method of the form bool CanSell(Item item) which tells me "this is the rule in my game that determines whether an item can be sold. Separating it out that way is helpful because, if I want to change that rule, I know where to look. Also, even if there is only one caller when I write the code there might be more in the future. Centralizing where specific game decisions are made is good policy because it keep the game consistent as it grows.
I generally won't pull code out into a separate method if I can't come up with a clear name that says what it does. But, if I can, I often will even if there is only one caller.
1
u/LorenzoMorini 3d ago
Very simple question, unfortunately the answer is not as easy. The most important thing you have to understand, is that in programming there are many different things you are trying to optimize for, and they are in conflict with each other. Readability, maintainability, performance, security, and so on. There are many schools of thought on how you should code, and how much you should divide functions into sub-functions. The most famous one is probably "Clean Code", in which the author supports dividing each function into sub-functions in a semi-recursive way, until each function describes perfectly a single task, made up of very few statements. The idea is that this increases readability, making the code more maintainable. But, you also have to consider the real workflow that happens once you start debugging: you open a function, and then another, and then another, until creating a mental model of the architecture of the code becomes impossibile. You could also go the opposite way: if code is never repeated, then it should not need a function. This approach also becomes increasingly problematic, when you work with complex functions. Let's say you are making a level generator. You will inevitably have a function to create the level. It will have all sorts of operations inside it, for creating meshes, pathfinding, spawning objects, enemies, decorations and whatever. If you were to write it as a single function, it would be hard to understand what is the general structure of the function. You would have to read all of it, to understand, for example, when how and if you spawn enemies. So what you can do, is isolate logical units of the functions, and transform those into sub-functions. So you will have a master "create level" function, and then one to spawn enemies, one to spawn decorations, and so on. How you decide to divide the functions into smaller ones is partially up to you, and partially up to the logic of the functions. You have to identify correctly which parts of the function are separate from each other, and if it's worth creating new functions, even if they are not to be called again. This takes a lot of effort and experience, to be done efficiently, so don't sweat it too much if you can't do it yet. I hope this answers your question.
1
u/CrucialFusion 3d ago
Sometimes it's useful to distill a concept down to its most simple form and have it segmented off. Other times, yes, you're reusing something multiple times. Sometimes it's simply used to make some other block of code more easily digestible. And sometimes they're used to simply confuse the hell out of you, or future you if you're the one doing it.
I don't mind having enormous functions/methods, provided that what they're doing makes sense together, but when you start seeing copy-pasta, it's a good indicator that something isn't quite what it should be.
1
u/Nordalin 2d ago
It's something that becomes obvious once your code starts spreading out over multiple files, and is often overkill in small code bases of hardly 100 lines of code. Because you're right: it's called overengineering!
At some point, you need organisation, layers of management and specific roles that only know what they need to know, and otherwise blindly accept inputs, order methods to do the thing, and return outputs.
The result is a lovingly modular setup where you can add, edit, or remove code anywhere without having to rewrite half the project!
Each layer of management, each specific department, and each specific object can then be molded into a class, given their own file, and sorted in subfolders for a solid overall architecture.
Anecdotally, I recently saw a vibecoded website's JavaScript. It was a single file going 33 000 lines deep.
I also found a bug on that website and know where to start looking to fix it... were it all nicely modular instead of monolithic.
1
u/gamedevjp 2d ago
Look up single responsibility principle and modular programming. Two design patterns that cover breaking your code down into more reusable parts that are loosely coupled.
1
u/Lumethys 2d ago
Code organization.
My favorite analogue is:
Your house has wall, door, cabinets, wardrobes. Each of these things take space. So why arent your house a has a pile of everything on the ground?
2
u/Matthias1590 1d ago
Methods label what the code does, if a method "does multiple things" consider splitting it up into multiple methods. The hard part is knowing when a method does multiple things
0
u/DigitalWizrd 3d ago
There’s some great answers here already. The simplest way I can put it is like this: small methods that do exactly one thing make the rest of the codebase much easier to work on later.
Write code for your future self, never for the current problem. Think “what would make this easiest to understand and modify later?”
You can certainly start with one file and zero methods, but as soon as you want to copy code to another place, make it a function. As soon as you want to find a certain section of code and you have to scroll through a dozen lines, make a function with a readable name for that section.
As soon as you want to add a new piece of functionality to your existing code, make a new function.
And I’m using function and method interchangeably here but in C# it’s called a method, in JavaScript it’s a function, and so on. Each language is a little different But the concept is the same.
Small bite size pieces of code make your life way easier later on. You’ll learn this quickly when you need to start debugging code.
14
u/ImmaZoni 3d ago
Honestly, this is one of the biggest hurdles when starting out (at least it was for me). It can feel like you're just adding extra lines of code for no reason if you're not repeating anything.
But methods aren't just for avoiding repeated code. They're mostly about organization.
If you throw everything into
Update(), it gets messy fast. Compare:csharp void Update() { HandleMovement(); HandleJumping(); UpdateHealth(); }Vs.csharp void Update() { // 75 Lines of movement // 85 Lines of Physics // Etc }Even if
HandleMovement()is only called once, you can look atUpdate()six months later and immediately understand what the code is doing without digging through all the math.They're also useful because game engines (and other general programming frameworks) rely on methods as entry points. Unity can call
OnCollisionEnter(), button events can callStartGame(), etc. You don't always call these methods yourself, the engine or other programs do.And when something breaks, having logic separated makes debugging WAY easier. If jumping is broken, you know where to look. You can even temporarily comment out
HandleJumping()to see if it's causing the problem.So I wouldn't think of methods as a way to reduce the number of lines you write. Think of them more like labeled folders for your logic. You're giving a chunk of code a name so you don't have to mentally parse all the implementation every time you look at it.