Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Anyone else ever feel like their programming is just plain bad?

Discussion in 'General Discussion' started by ptgodz, Jul 31, 2017.

  1. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    (they do matter in any type of collaborative projects, in my opinion)

    Wise words right there @mysticfall
     
  2. Deleted User

    Deleted User

    Guest

    I'm just not a fan of when things go the way of "stack exchange" where people expressly say this is the "only" way to do things. It's plain wrong and ultimatley it's a question of how quickly your workflow works with or against you..

    Now this isn't really anything to do with you, it's just a somewhat fringe annoyance I've come across from time to time. I've worked on enterprise systems in telecommunications and ultimately it's not massively different but it is different (dependant on what you're doing of course).

    No you shouldn't re-factor continuously (IMO), I work with a semi-derivative modular master client architecture just because it's been drilled into me to do it that way.. I try my hardest to hook as little as possible so if I change things I don't have to then change other things which then breaks other things in a massive cyclical crap house. So I do re-factor but I don't do it often as I have no need to (also don't want to because it opens you up to more bugs).. I rarely repeat and my variables etc. are as informative as they can be, I try to make sure my code is at least simple to follow so I can maintain "readability" for nothing else but sanity's sake.

    Which collectively is the whole point of modern "modular" game engine theory and when you're working with large projects (even on top of a pre-made engine) does make life a hell of a lot easier.

    TDD again IMO is more inline / useful with other engines where you don't have instant feedback w/ unit "style" testing, in Unreal the hot reload function can be a little "hit or miss" and in LY (where you have to compile the whole bloody thing when you make a change) it is prudent to factor in requirements before writing code (like TDD) again as opposed to unit testing..

    Thing is, I don't really consider these "best practices" I consider this common sense which comes with experience. In short whatever causes me the least amount of headaches down the line.

    I believe I do it by default and don't really think about it, so that's something to consider.. I'm not saying your opinion isn't valid and or worthy of consideration, I still don't believe comments are a massive issue and yes, I have worked on many projects from small games solo to teams making MMO's / engines and engine contributions.. Ultimatley in terms of collaboration communication is key and that certainly applys to more than games.

    As much as I dislike agreeing with @hippocoder, he is right on projects large and small they often fall very short whether following these practices or not because time is the biggest factor.. If that wasn't the case there wouldn't be as many instances of train wrecks released from large budget studios (especially on PC)..

    Best practices are fine until they become at loggerheads with efficiency, mentioning again the "trainwrecks" from large developers who I'm pretty sure will follow these principles ultimatley they should of spent time on efficiency to release a playable product.

    This is shadows final thought, work smart not hard :)...
     
    mysticfall likes this.
  3. derf

    derf

    Joined:
    Aug 14, 2011
    Posts:
    349

    This is true, but I currently do not have a repository setup for code...yet.

    I was thinking of setting up my private Microsoft account cloud repository feature, but I have been putting it off. So for now I add in a small comment on a change until then.
     
  4. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,133
    That's definitely how I was when I was younger / less experienced / more perfectionist.
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,133
    To me, the value in ongoing refactoring seems to be in large, long-term projects.

    It's all about cost vs. return on investment. The cost of refactoring is a bunch of hours spent changing something that already works properly*. The thing already worked, and the best case result as far as a player is concerned is that there is no visible change... so what's the benefit? It's entirely to the developer, and in a practical sense it's solely about making future work on that same piece of code more efficient.

    So the question is, will the future efficiency bought by the refactor save more time than the refactor will cost? (And remember the cost isn't just the time updating the code, there's also the related testing/QA time.)

    If developers are working directly with something every day/week/month for months or years then heck yeah, spend a few hours or days making that as efficient as possible because it'll probably make the cost back many times over. If it's not going to save time later, though, then don't waste your time on improving it now.

    In short, players don't care about "code quality", developers do. Code quality only matters in the places where it will effect developer productivity. So even if something is ugly, if it works and doesn't reduce productivity then leave it alone - your players don't care about it, and you've got plenty to do that they will care about.

    * If it doesn't work properly then you're not "refactoring" it, you're "fixing" it, and that's a completely different proposition!
     
    neginfinity, Kiwasi and Deleted User like this.
  6. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,726
    Well I think there's a grey area between making things work better together and changing the entire class around. Both are technically refactors. Even making a function return bool success is technically a change in how it does the same job, so it would be a refactor.

    The idea is if the refactoring is pretty much factored in, it can hurt a lot less. But I still approach large refactors with utmost caution because changing so much will break something.
     
  7. yoonitee

    yoonitee

    Joined:
    Jun 27, 2013
    Posts:
    2,284
    Well, I never feel like I'm an expert at programming. Its, a tool, a necessary evil to make a game. But that's why I don't like to work with other programmers. Also, I'm kind of bored of programming, that's why I'm giving it up to be an animator.
     
    dogzerx2 likes this.
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    Very valid. I've got a triangulate class I use commonly. It takes an array of points and returns a list of triangles for a 2D. Its pretty ugly on the inside. But the thing is it works correctly. And it has a good API. And it barely interacts with the rest of my code. Given those points, I would get zero payback from going in and fixing the internals.
     
    frosted, dogzerx2 and neginfinity like this.
  9. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    If you dont maintain your code, refactor, etc, it will sooner than later stop working properly and then the players will care about code quality
     
  10. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,133
    Code does not decay. If I grab a 10 year old piece of code it will still do today exactly what it did 10 years ago. The only thing that will stop it working properly is some external change.

    Note that "maintenance" and "refactoring" are not the same. Maintenance is often about managing external changes, like updating code to use a new version of a library or something. That stuff can be important. But on the topic of refactoring in particular, no, a piece of code that previously worked will not just "stop working properly" because it hasn't been refactored.

    It might become an utter pain in the bum to work with, but I covered that already. ;)
     
    frosted, Kiwasi and Ryiah like this.
  11. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    I have to differ on this one, since I believe a bad piece of code can grow much worse if left unattended. Actually, that's why such a problem is often called as a 'technical debt'.

    Roughly speaking, it can happen in two different ways. Firstly, it is possible that the said code is some sort of an API that other parts of the system depend on. As others who seem to be more cautious or reluctant to refactor often in this thread have said, changing such code on which many other parts depend can be quite time consuming or even dangerous.

    In software design, a 'badly designed code' often means a piece of software that is not flexible enough to be extended easily. So, when we find an unforeseen requirement that needs to add new features to such a component, or extend its existing functionality, it is often the case that it can only be made possible with an ugly hack.

    Even if it takes less time to write such a workaround than to revise the design to accommodate the new requirements, such overhead can add up, as more and more other components come to depend on it, until it become prohibitive to fix the problem due to time constraint of the project.

    If we can call this a structural version of how a technical debt can happen, I think we can say there's another type of such a problem, which is more like an 'epidemic' in that it can spread through the codebase, if left unchecked.

    In many cases, even seasoned programmers learn something new - be it some knowledge of domain, or about the programming language itself - as they progress with their projects. And often they find recurring problems, like searching or copying collections for example, for which they just reuse (namely, copy & paste) the solution they found the first time.

    If, for example a developer used SendMessage API to handle in game events, for example, but for some reason decided that it's much better to use delegates later, he or she can easily change (or 'refactor') the code if there are only a few occasions where such an API was used.

    But if the developer feels lazy, so just keeps duplicating SendMessage calls throughout the codebase, it will soon become a matter of changing hundreds of lines and doing tests to make sure that it won't break things that worked before.

    The whole point of a constant refactoring is to get accustomed to such a practice to continuously write and improve the code by small measures, so that one can (hopefully) eliminate either of such extremes, namely that of doing a large scale and dangerous refactoring later on, and that of just giving up improving code quality at some point and feeling depressed at the mess it becomes.
     
    Last edited: Aug 4, 2017
  12. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,133
    Yeah, I totally agree with that. All I was saying in the post you quoted was that a lack of refactoring (which is what I was talking about in the post before that) will not cause something to "stop working properly" if it already worked.

    In my post before that I pretty strongly advocate for making sure that code you work with regularly is efficient to work with:
     
    frosted and mysticfall like this.
  13. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    sure if you never touch the code again, ever. Seldom the case in any project. You might want to add features, etc. tweak something etc. And to work in a utter pain project as you describes it will make people make mistakes too because of just the sheer misery working in such a project.

    I often wonder what went wrong with Flashpoint/Arma franchise, they basically still have the same clunky mechanics and bugs that were present in the first Operation flashpoint game back in early 2000. Thats a code base that has survived a long time :D (Love the games no question about that)
     
    frosted and mysticfall like this.
  14. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    7,547
    How did you design your inventory system, did you use an array of objects or of gameObjects or a Dictionary lookup system so you can store your inventory as enums?

    Did you use any design patterns?
    Is the Aggregate pattern the ideal inventory base?

    If I remember right the Aggregate pattern allows a class to store lots of objects of it's type e.g. magic pockets within pockets or sub components e.g. Crafted items.
     
    Last edited: Aug 4, 2017
  15. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,389
    A decent way to design an inventory item is to use ScriptableObject-based classes to describe item configuration (item name, number of items per stack, effects, value, etc). The item configuration can later be stored in a field of a component that represnets the item in-game, or could be referenced within a class that represents inventory. A single scriptable object is already unique, meaning you wouldn't be limited by predefined enum, and it would be possible to have any number of item types. And, yeah, I believe you can use scriptable object as a dictionary key too.
     
  16. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    7,547
    Would that allow for crafting and aggregation or sub containers and user defined objects e.g crafted weapons?
     
  17. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    16,211
    They're basically just a way to access and modify data from the inspector panel. You can create a new instance at runtime, load the necessary data into it, and serialize it down for when it is needed next time.
     
  18. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,873
    There are two sort of situations in which I realize I'm a bad coder.

    One is when I build an impossible contraption impossible to manage. So I know I'm either doing it wrong, or doing it right yet biting more than I can chew ... in both cases: bad coder.

    But also it happens when I'm making some codez, and somewhere along the way I realize I could have done it better and shorter and faster, if only I had done it some other way.
    Sometimes I'd delete big chunks of code and replace with the new smarter way (other times I just leave it as it is ... as long as it works)

    So sometimes being a bad coder is being a better coder!
     
  19. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    7,547
    This is could be a bad coding habit, what you can do is keep the old way and add the new, potential benefits you can test the new against the old and also compare the two in the profiler.

    Note: this A/B coding strategy is used by John Cormack (Doom).
     
  20. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    With the help from modern IDEs and source code management systems like Git, it became really easy to switch between code history and compare them whenever it is required.

    So I think there's little reason now to leave the old code to clutter the codebase when doing such kind of a refactor.
     
    AndersMalmgren likes this.
  21. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    So very, very true. When I see code blocks that are made inactive through comments (aka poor mans versioning) I always see it as my duty to give said programmer a hard time :p
     
    mysticfall likes this.
  22. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    7,547
    I wouldn't expect you to leave the old code in, just take it through a transition and test phase until you are happy with the new.

    Potential benefits of using this approach you might be tempted to try different algorithms or ways of coding a subsystem just to see if it's better than your current solution.

    You can also have the knowledge that your new solution is faster/cleaner/better than the old one as you can compare and contrast.

    How many times have you found a performance problem and gone in optimising and changing the code getting incremental improvements that seem less and less to the point you stop suspecting your new optimised code is only a tiny fraction faster than the old. With an A/B or A-G approach you can test and compare the actual improvements.
     
  23. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    I have done that a few times with our game, I create a feature branch, refactor, commit to that branch, then profile. Switch to source branch and profile.
     
  24. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    I agree that A/B testing could be a very effective approach in optimizing code. But the point is, you don't have to leave your old code until you are satisfied with your modifications.

    It's much easier to delete the old one and work with branch/diff/stash/etc to compare them, than working with two different versions of the code at the same time, possibly by commenting out or renaming one of them.
     
    AndersMalmgren likes this.
  25. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    Plus, its no guraantee you end up with the old version when you uncomment. With a versioning tool you are guaranteed to end up with the old version. Minimize human errors folks!
     
    angrypenguin and Kiwasi like this.
  26. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,822
    I actually disagree on this in respect to game dev specifically. I've found there to be more systems that I almost never touch again in game dev than in anything else.

    In my experience, often times, once a system or subsystem is written - I switch from 'producer' to 'consumer' - I use the components largely as black box as I switch to tasks like level design, content production, etc.

    If a set of components or a system works well enough, then I rarely, if ever, look at the code again.

    This is something that is extremely different from most other software development, largely due to the fact that there's no real analog to "level design" or "content production" in traditional software. The closest analog is probably data entry 'admin' systems in web dev, and that's not remotely similar in most cases, as it's not nearly as complex, open ended or functional. These systems are usually largely text entry systems, it's very rare that users can add behavioral functionality in the same way that's needed in games.
     
    angrypenguin and Kiwasi like this.
  27. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    If the are of a black box type it's very easy to write unit tests for them, now you can refactor their internals the best you like ;)

    I only speak for myself, me and my brother that is the team for our game are both system arcitechs, but in the enterprise world. We write the game in the same way we would a enterprise system, we have unit tests we try to be as agile as possible, plus we are a early access title, the game is shaped as we move along, using community feedback, if I were to check git history I'll bet 90 procent of all classes have atleast 2 commits to it.
     
  28. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,873
    I have never done A/B coding strategy, that's too leet for me ... but keeping old code before making some big change is logically important ... even for the the simplest of reasons: you may realize half-way through you can't be arsed to re-do the whole thing. Don't burn bridges.

    Time is too short to be hungry for perfection. Sometimes if you have a good idea, keep it in your pocket and apply it next time you have a chance.
     
  29. kaiyum

    kaiyum

    Joined:
    Nov 25, 2012
    Posts:
    622
    Rome wasn't built in a day. Have patience. Make it as a love if you can. I too came from different background, ridiculously different. Now things have been changed so much around me, recently I completed a M.Sc in CS. Yes formal education can help you a lot. That you will learn things in an interesting progression. Its just, things take time and effort depending upon the situations, target goal sets. Making a flappy bird and making the "heavenly sword" are not the same and similar processes.
     
  30. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,822
    No it's not. Just because a system is complete and usable at a user level doesn't mean the functionality is easy to write automated tests. At the end of the day, most of my code is dogfooded. A great deal of my code is written so that I can use it as consumer later.

    Some of these systems have had countless revisions and rewrites in order to make them robust enough and easy enough to use in order to be truly useful.

    This is probably my most extreme example:


    This kind of thing is not remotely easy to test. Further TDD would have hindered the design iteration required for me to figure out how to make the tool solid for practical use.

    A lot of the code for this tool is a disaster, I should entirely rewrite it. But it works very very well for what I need it to do.
     
    angrypenguin, Kiwasi and Peter77 like this.
  31. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    Actually, it's both easier and safer simply to delete the old code and start working on new one, if you are using a source management system like Git (and probably you should, if you haven't already).

    If you rather comment out the old code or rename it, it becomes quite cumbersome to switch between two versions, and there's a possibility that you might miss out some parts of the code that should be restored or deleted upon switching, especially when each version requires a slightly different set of import statements, or if it involves editing multiple source files.

    At the very least, deleting old code is not considered a bad practice, but on the contrary, it is generally discouraged to leave any unused code in your project.
     
  32. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    As to the value of continuous refactoring or of unit testing, I believe that it all depends on how much requirements or scope change is expected within a lifespan of the project.

    I can see why such software engineering practices are not so eagerly embraced by the game industry, because in general, game projects have a much shorter lifespan than the other types of software development, thus rendering maintainability a secondary concern.

    But probably it would be inaccurate to say that they are useless in any kinds of game development, because some game related development seem to have much longer lifespan than the rest.

    For instance, it is easy to imagine that MMOGs and framework or library type projects would be expected to last at least couple of years, during which they might meet with frequent scope or requirements changes. And in such cases, it might make more sense to employ such common software engineering practices which can help make the codebase more flexible for changes.

    And I also suspect it might also depend on each developer's personal preferences or background to some degree. For instance, I can imagine there could be many who wouldn't tolerate their game objects or prefabs to have inconsistent names or weird structures, even though it doesn't affect the game at all.

    Probably it is just that we all require those things we work with the most frequently to be well organized according to our own preferences or principles. So, if one has a strong artistic background but has only minimal familiarity with programming, it's likely that he or she will try to keep all the art assets well organized, while not really care about 'scripts' as long as they work as expected.

    On the other hand, those who like myself who have a strong background as programmer, but lack professional experiences as an artist, might not even notice if there's some inconsistencies in their art assets, but feel it quite stressful if they notice some badly written code but unable to improve it due to time constraints.

    So, I believe it mainly depends on the type of the project and of those who work on it.
     
    Last edited: Aug 6, 2017
    frosted likes this.
  33. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,726
    Mr Cormack (Doom) is actually doing what's known in the trade as parallel running. Businesses never switch over straight away, instead for a while, the new method runs in parallel to the current method until everyone is happy it works.

    It's not A/B split.
     
    ikazrima likes this.
  34. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,873
    Ideally you save backups outside your project. And if it's a large important backup, outside your hdd or local storage.
     
  35. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    You use git, end of story!
     
    angrypenguin, dogzerx2 and mysticfall like this.
  36. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,726
    I use an automatic nightly backup onto another drive, it's sloppy and not external. I do manual backups here and there. The rest is backed up over Unity collab, which on the other end has further distributed backups from team members. So we are basically able to retrieve the project in event of nuclear war and floods. I am not sure I would like to test it though.
     
    dogzerx2 likes this.
  37. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,873
    Eep!!! *runs away*
     
    AndersMalmgren and hippocoder like this.
  38. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,726
    Unity collab is good though. It just works and you can roll back and you do have access to it anywhere. It's a pretty good backup solution TBH
     
    angrypenguin likes this.
  39. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    @hippocoder Havent looked at it, we use GIT with GIT lfs. If Unity collab uses that under the hood then its good :D

    Once you go distributed you never go back to none distributed :p
     
  40. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,822
    I've spent a lot of time thinking about the differences in my experience writing game code vs heavy data processing vs UI (web and desktop traditional). As well as the differences working in large enterprises, small teams, and now solo.

    Each domain/team organization really has it's own set of concerns. I plan to write a very long, very high detail article on the subject at some point.

    Ultimately, the hardest thing to deal with in code is change.

    But the kinds of changes that you encounter in each domain is super different, the process for dealing with change requests in an enterprise environment dealing with extremely valuable data is on an entirely level from the kinds of requests you get on pure GUI, and so on.

    I imagine the kinds of changes you may encounter in an FPS like Battlefield is very, very different from a strategy game like Civilization, which again is very different from a traditional RPG like Pillars of Eternity.

    Applying "one size fits all" design to problems that really run such an immense gamut of needs and process means you are simply not being efficient.
     
    mysticfall likes this.
  41. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    I'm looking forward to your article, as I've only recently began to experience the other side of development and have been wondering about the same question. :)

    By the way, are we talking about the same type of 'change'? I'm asking this, because I have a suspicion that you seem to refer to changes of in-game state, whereas what I meant by the word was about the source code itself.
     
  42. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,822
    I mean functionality change.

    Raw Data: "hey we need a new column, and this relationship has to change"
    UI: "When the user clicks here, can we show this toolbar?"
    Game: "hey, what if instead of a skill tree, we used skill runes that are interchangeable?!"
     
  43. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    @frosted Ok, I got what you meant now. Thanks for the clarification!
     
unityunity