Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411273 Posts in 69323 Topics- by 58380 Members - Latest Member: bob1029

March 28, 2024, 12:54:17 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)To refactor or not to refactor?
Pages: [1] 2
Print
Author Topic: To refactor or not to refactor?  (Read 3410 times)
Flavioli
Level 0
*


View Profile
« on: April 29, 2013, 12:05:37 PM »

I'm sure I'm not alone here, but there have been many times in large projects where I felt I was approaching everything with the correct design, only to eventually find that my implementation becomes somewhat clunky and hard to sustain. The big thing I always ask myself, in these scenarios, is whether or not it's worth the time and loss of momentum to sit down and refactor the code to make things a bit more organized and easy to work with. The problem is that refactoring is not free... sure, it might save you time in the future, however, not only does it cost time now, but it also stops the flow of steady progress in the game, which has caused me to abandon a project more than once.

So my question to the community... say you do run into the situation where you find that your code becomes clunky enough that refactoring crosses your mind... do you always refactor, or do you just push onwards with the dirty code, or does it depend? Do you find that there are situations where refactoring is a must, or that there are situations in which refactoring is never a good idea? I used to think this was a no-brainer, but I know several indie game devs that are strongly against refactoring because they feel that the loss of momentum always overpowers the gain from the cleaner code. What is your opinion on the matter?    
« Last Edit: April 29, 2013, 01:36:03 PM by Flavioli » Logged
SoulSharer
Level 1
*



View Profile
« Reply #1 on: April 29, 2013, 12:20:54 PM »

I'm sure I'm not alone here, but there have been many times in large projects where I felt I was approaching the everything with the correct design, only to eventually find that my implementation becomes somewhat clunky and hard to sustain. The big thing I always ask myself, in these scenarios, is whether or not it's worth the time and loss of momentum to sit down and refactor the code to make things a bit more organized and easy to work with. The problem is that refactoring is not free... sure, it might save you time in the future, however, not only does it cost time now, but it also stops the flow of steady progress in the game, which has caused me to abandon a project more than once.

So my question to the community... say you do run into the situation where you find that your code becomes clunky enough that refactoring crosses your mind... do you always refactor, or do you just push onwards with the dirty code, or does it depend? Do you find that there are situations where refactoring is a must, or that there are situations in which refactoring is never a good idea? I used to think this was a no-brainer, but I know several indie game devs that are strongly against refactoring because they feel that the loss of momentum always overpowers the gain from the cleaner code. What is your opinion on the matter?    

If it is bearable I'd live with it. It might not worth the time you could spend on other projects. Basically you might be wasting your life refactoring. I saw a lot of clunky, bad code in commercial projects and they still work, does it mean that games are bad by themselves? No. (check out Jedy Academy sources, you might be surprised)
Not to mention refactoring most of the time is only related to single project. (and thrown away with it)

In the end I believe you should just skip it, if it doesn't make development go slow.
This is my take on that.
« Last Edit: April 29, 2013, 12:31:46 PM by Yaroslav » Logged

Twitter: twitter.com/SoulSharer
Skype: disturbedfearless
rosholger
Level 1
*



View Profile
« Reply #2 on: April 29, 2013, 12:25:37 PM »

no general wisdom words here but lately i have started to notice that my current project, or at least the player class, is becoming more and more dirty. i have tried to fix this multiple times but now i have just given up, it runs fine and its pretty much only that class that's a mess so i will just live with it.
Logged
Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #3 on: April 29, 2013, 01:30:18 PM »

So my question to the community... say you do run into the situation where you find that your code becomes clunky enough that refactoring crosses your mind... do you always refactor, or do you just push onwards with the dirty code, or does it depend? Do you find that there are situations where refactoring is a must, or that there are situations in which refactoring is never a good idea?

To my mind, working on any given programming problem - be that new functionality or cleaner code - is only ever worthwhile if it facilitates something important to the project. But that doesn't mean never refactor - "something important to the project" could be your peace of mind, it could be maintainability, it could be low bug count... it doesn't have to be end-user-visible features.



If you spend ten hours refactoring in order to shave two hours off the next feature you implement, it could have been a waste of eight hours. On the other hand, if you're going to be implementing ten new features then two hours off of each of them is ten hours saved overall.

If you're worried that the mess of code you have makes future bugs more likely - especially if they'll be hard-to-debug bugs like numbers that feed into something else being ever-so-slightly off - then it may be worth refactoring because you can't tell how much time you'll waste trying to track down those bugs (and/or how much motivation it will sap).

If you find that just knowing that there's that horrible bit of old messy code in your project makes you less motivated to work on your project, then it's probably worth refactoring just to make yourself more happy.

If the next piece of work you do will make the messy code messier, compounding the problem and meaning it'll take longer to refactor in the future, it may be worth tidying it up now so you can set out on the right foot and not introduce more work for yourself later.




For example, I'm about to do some refactoring in my current project to tidy up the way AI is handled. Originally I had an abstract 'Fighter' class, a 'PlayerFighter' class implemented in such a way as it takes player input and an 'AIFighter' class which makes its own decisions. Now I'm planning to tidy that up to have the Fighter class defer all decisions to a 'brain' class, and implement the player-selection or AI-decision there, so that AI fighters can use vehicles and equipment in the same way as player fighters... because otherwise they'd have to have their own special vehicle classes and it wouldn't be possible for the player to steal enemy vehicles (or vice versa!). I noticed how awkward the class hierarchy was in this area ages ago, but I'm only bothering to do something about it now it's actually preventing me from doing something else.
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
eigenbom
Level 10
*****


@eigenbom


View Profile WWW
« Reply #4 on: April 29, 2013, 02:43:05 PM »

I love cleaning, refactoring and redesigning parts of my engine all the time. It'll take me longer to finish my game as a result, but the benefit is that I have an engine that works better and is easier to use. There's definitely a place for rapidly building something, although I would call those 'software sketches' rather than stable commercial products. I can think of a few games built this way, and unfortunately they become plagued with bugs which ultimately ruins the player experience. But otoh I can also think of many games (DNF) which went through too much refactoring/redesigning.
Logged

Brainswitch
Level 0
**



View Profile WWW
« Reply #5 on: April 30, 2013, 05:00:05 AM »

I love cleaning, refactoring and redesigning parts of my engine all the time. It'll take me longer to finish my game as a result, but the benefit is that I have an engine that works better and is easier to use.

I too love "cleaning, refactoring and redesigning" of my code/engine... But I tend to do it a bit too much, therefore I've only 'shipped'/'completed' very few games...
Logged

Sar
Level 3
***


Likes Violins


View Profile WWW
« Reply #6 on: April 30, 2013, 05:28:13 AM »

There's definitely a place for rapidly building something, although I would call those 'software sketches' rather than stable commercial products.

While it's true that rapidly building something without heed to stability to get a working prototype up is more of a sketch and shouldn't ever be sold, there's a huuuuge middle ground between that and refactoring everything to have the absolute cleanest and nicest code ever when you ship.

Not-refactoring is absolutely not guaranteed to give you any more bugs than refactoring... and refactoring can equally introduce bugs.
Logged

Currently working on: Chronicle of Mars
Previous Projects: [Käfer|Tristan and Iseult(TIGS)]
beck
Level 0
**


View Profile
« Reply #7 on: April 30, 2013, 09:11:38 AM »

In the end your system would be better for it, but the question is whether your system is the most important part. Would your game suffer from this refactoring? Massive reworks can sometimes break a lot of peripheral stuff, and even kill some of the "magic" that makes your game fun in the first place. If you can successfully refactor in a short amount of time, then great, but that's a pretty tough gamble to make.
Logged
ericmbernier
Level 3
***


Sometimes I make games.


View Profile WWW
« Reply #8 on: April 30, 2013, 11:43:58 AM »

Up to this point I've only developed smaller Flash games that I don't go back to often, unless I'm borrowing bits and pieces of code for my next game. Due to this, I don't refactor often, if ever, as it would be a complete waste of time for the size of my projects. Also, it would get in the way of making more games!  Smiley

However, I have a day job as a C# developer, and have refactored many classes that were originally written by scientists, who didn't have much of an idea when it comes to OOP. In this instance, refactoring code saved me a lot of time in the future, and was well worth it.
Logged

nikki
Level 10
*****


View Profile
« Reply #9 on: May 01, 2013, 01:23:45 AM »

I'd say it depends.

I like to use architectural metaphors to think about programming.
Sometimes ducttape is nice.
Sometimes you're better of building a steady concrete foundation.

do not build a highrise building on a foundation of ductape and plywood.
do not change the foundation when the building is done and you only want to put a window in.

but all metaphors aside: it depends.
  
I personally love refactoring though and do it very often.
So often it doesn't feel like "stops the flow of steady progress" at all.
Instead it is steady progress.

Logged
Muz
Level 10
*****


View Profile
« Reply #10 on: May 01, 2013, 03:14:06 AM »

If you're driving in mud, you're constantly losing momentum Tongue

Always:
- Move repetitive things into functions
- Rename retarded variables like $buffer['dataset3'][1]['data'] into something legible like $totalItems

Occasionally:
- Delete old commented out code (after committing it)
- Remove constants from code, i.e. never have a 'int attack = 20 + dice()'. Store it as 'BASE_ATTACK = 20; int attack = BASE_ATTACK + dice()'. Just in case you tweak values later.

Don't bother:
- Rewriting code into 'better code' (without finishing the game first)
- Adding in comments if it's intuitive (e.g. java code and intuitively named functions and variables)

Never:
http://www.joelonsoftware.com/articles/fog0000000069.html


Anyway, my rule of thumb is that you shouldn't keep more than 3-4 things on your brain while coding. If you're going to switch through multiple files, or scroll to different parts of the page, you should probably refactor. A variable name like $buffer['dataset3'][1]['data'] is horrible, because every time you look at it, you wonder what dataset3 is, what dataset2 is, what else is in the buffer, what the buffer is used to store... and so on.
« Last Edit: May 02, 2013, 08:01:31 AM by Muz » Logged
Gregg Williams
Level 10
*****


Retromite code daemon


View Profile WWW
« Reply #11 on: May 01, 2013, 03:43:19 AM »

Sometimes a total rewrite makes sense, but yeah its certainly something to avoid.
Logged

ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #12 on: May 01, 2013, 07:32:31 AM »

- Remove constants from code, i.e. never have a 'int attack = 20 + dice()'. Store it as 'BASE_ATTACK = 20; int attack = BASE_ATTACK + dice()'. Just in case you tweak values later.

I've seen this overdone. If the constant is only ever used on that one line, it's perfectly clear as-is, and defining it separately is just going to muddy your code. If it's used more than once though, definitely #define it to avoid accidental bugs from changing one instance and not another.
Logged

Gregg Williams
Level 10
*****


Retromite code daemon


View Profile WWW
« Reply #13 on: May 01, 2013, 08:13:59 AM »

- Remove constants from code, i.e. never have a 'int attack = 20 + dice()'. Store it as 'BASE_ATTACK = 20; int attack = BASE_ATTACK + dice()'. Just in case you tweak values later.

I've seen this overdone. If the constant is only ever used on that one line, it's perfectly clear as-is, and defining it separately is just going to muddy your code. If it's used more than once though, definitely #define it to avoid accidental bugs from changing one instance and not another.
Also probably should define it if its likely to change during development. It's much easier to update a define at the top of a file than have to find a magic number in the code to change.

I'm actually starting to use lua for this, just so that I can edit values and reload them, without a recompile and relaunch.
Logged

J-Snake
Level 10
*****


A fool with a tool is still a fool.


View Profile WWW
« Reply #14 on: May 01, 2013, 03:39:07 PM »

The bigger your system gets, the more structure/abstraction it needs. A small project can get away with dirty code and still offer bugfree functionality. So overall finding a healthy middle-ground is a good compromise.
Logged

Independent game developer with an elaborate focus on interesting gameplay, rewarding depth of play and technical quality.<br /><br />Trap Them: http://store.steampowered.com/app/375930
Muz
Level 10
*****


View Profile
« Reply #15 on: May 01, 2013, 09:10:25 PM »

- Remove constants from code, i.e. never have a 'int attack = 20 + dice()'. Store it as 'BASE_ATTACK = 20; int attack = BASE_ATTACK + dice()'. Just in case you tweak values later.

I've seen this overdone. If the constant is only ever used on that one line, it's perfectly clear as-is, and defining it separately is just going to muddy your code. If it's used more than once though, definitely #define it to avoid accidental bugs from changing one instance and not another.

Yeah, depends on the situation. I've overdone the whole (i + 1) -> (i + INDEX_NUMBER_FOR_THIS_THING) thing before, wasn't smart. Better to put a comment saying this is a 0 or 1 index.

But if you're sharing code, you should use constants. int attack = BASE_ATTACK + dice() is just a lot easier to understand at a glance than 20 + dice(); You can even declare the constant in the line before it, instead of up in the #define or whatever. It will act as a comment, and the compiler will optimize it anyway.



Sometimes a total rewrite makes sense, but yeah its certainly something to avoid.

If you're going to rewrite it, treat it as a different game (e.g. Spiderweb Software's Avernum vs Exile). If you're going to make a sequel, use the same engine as far as you can. Once it becomes so outdated that you can't make money or whatever, then you do a full rewrite. You're also strongly cutting down costs by reusing a 'weak' engine. Most broken engines are much easier to fix than rebuild.

And quite often by the time the engine is so cluttered up and archaic that it needs to be changed, there's a better open source alternative.
Logged
Gregg Williams
Level 10
*****


Retromite code daemon


View Profile WWW
« Reply #16 on: May 01, 2013, 09:36:08 PM »

Sometimes a total rewrite makes sense, but yeah its certainly something to avoid.

If you're going to rewrite it, treat it as a different game (e.g. Spiderweb Software's Avernum vs Exile). If you're going to make a sequel, use the same engine as far as you can. Once it becomes so outdated that you can't make money or whatever, then you do a full rewrite. You're also strongly cutting down costs by reusing a 'weak' engine. Most broken engines are much easier to fix than rebuild.

And quite often by the time the engine is so cluttered up and archaic that it needs to be changed, there's a better open source alternative.

Yeah thats a very good point, when it comes to games. I was admittedly thinking of internal tools when I answered. The type of thing that your going to be maintaining and updating for X years. In this area I've come across situations where its just hugely more cost effective over the long term to rebuild the tool from the ground up. That said I'd be hugely hesitant of ever re-writing a game that has a decent amount of progress.
Logged

Archendrus
Level 0
**



View Profile
« Reply #17 on: May 03, 2013, 10:13:37 PM »

Ahhh refactoring. It's so easy to be working on your game and notice something that you think could be designed or written a little better and then bam, a week or more has gone by and your game isn't any closer to being finished.  I've done it so many times.  

Refactoring can be a trap, one that I learned about the hard way...several times. So personally I don't think it's worth breaking your stride unless your code needs it because of performance issues, or it's code that your going to reuse in many projects.  If it's the second case, I wouldn't start the refactoring process until after the current project is finished.  
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #18 on: May 04, 2013, 10:15:29 AM »

- Remove constants from code, i.e. never have a 'int attack = 20 + dice()'. Store it as 'BASE_ATTACK = 20; int attack = BASE_ATTACK + dice()'. Just in case you tweak values later.

I've seen this overdone. If the constant is only ever used on that one line, it's perfectly clear as-is, and defining it separately is just going to muddy your code. If it's used more than once though, definitely #define it to avoid accidental bugs from changing one instance and not another.

Yeah, depends on the situation. I've overdone the whole (i + 1) -> (i + INDEX_NUMBER_FOR_THIS_THING) thing before, wasn't smart. Better to put a comment saying this is a 0 or 1 index.

worse
inc(i); // Who, Me?
Logged

ThemsAllTook
Administrator
Level 10
******



View Profile WWW
« Reply #19 on: May 04, 2013, 01:02:18 PM »

Refactoring can be a trap, one that I learned about the hard way...several times. So personally I don't think it's worth breaking your stride unless your code needs it because of performance issues, or it's code that your going to reuse in many projects.  If it's the second case, I wouldn't start the refactoring process until after the current project is finished.  

A third, more common (for me at least), and harder to plan for case: When your code has become too brittle to work with anymore, and you'd spend less time refactoring than you would getting the code to do what you want as-is. Let a system go without refactoring for long enough, and it tends to harden to the point where it becomes impossible to change anything. There's of course no way to look into the future and see how much time you'll save from refactoring, so you just have to trust your intuition to know when it's time to do it.
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic