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. ptgodz

    ptgodz

    Joined:
    Aug 4, 2016
    Posts:
    99
    I've only been doing unity on and off for about 10 months, coming from a background of no coding experience.
    I cant help but feel sometimes like i'm just not getting it. I've wrote a script today for my basic inventory in my game and I can't help but feel its just a bad way of going about it.

    Anyone else ever feel like that? I think because I don't fully understand everything I just feel like I'm making a meal out of nothing. I understand variables, access modifiers, loops, etc, but admittely struggle with things like delegates.

    How long did it take you to feel like you were writing code that you could actually show to people and feel confident about it?

    Edit: Just one point, I DO feel a buzz when I get something working, however basic it does give me a bit of a natural high, despite it probably being ridiculously bad code haha.
     
  2. Aiursrage2k

    Aiursrage2k

    Joined:
    Nov 1, 2009
    Posts:
    4,835
    Take a programming course at your local college
     
  3. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    7,175
    Or don't.
     
  4. AntoineDesbiens

    AntoineDesbiens

    Joined:
    Jun 9, 2014
    Posts:
    843
    //opinion

    I learned to code online and here's how it went for me.

    I didn't have a clue what I was doing at first, kind of like you, feeling like I didn't know if what I was doing was right or wrong. For the first year and a half-ish, it was about getting things to work.

    The more I coded, the more I had to look up stuff online, the stronger my grasp of programming concepts in general became.

    For a long time, I wished I had formal education, someone that would confirm if what I learned was right, or wrong. Now I feel good about my abilities. I'm no wizard, but I feel like I can tackle some decent challenges and I feel comfortable when there's programming talk.

    So, in my opinion, I sincerely don't think that formal education is mandatory (certainly not saying it doesn't help). Experience will take you where you want to get. I recommend creating a good balance between having fun and learning. That will keep you going and as the time passes, you'll become better. Also, try to stay out of your comfort zone.
     
    Kiwasi, ptgodz and EternalAmbiguity like this.
  5. FrankenCreations

    FrankenCreations

    Joined:
    Jun 14, 2017
    Posts:
    304
    I will answer your question rather than give some lecture on what I think is the best way to learn.

    Yes.....yes I do.
     
    bart_the_13th and Scabbage like this.
  6. RichardKain

    RichardKain

    Joined:
    Oct 1, 2012
    Posts:
    1,258
    Practice, it's all about practice.

    When I look back at the code I made a year or two ago, I see all sorts of inefficiencies and errors. Regular practice and research has taught me all sorts of new techniques and approaches. I've been exposed to different ways of thinking about the structure of my code. The code I make today is much cleaner. I imagine the code I make a few years from now will be better still.

    The one problem with this is I am constantly tempted to go back and update my previous projects. With my improved coding, I always want to return to my past projects and re-construct them with my new skills. But you can't spend all your time refactoring. So I have to pick and choose my battles.
     
  7. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    I didn't really ever feel this way because I started programming as a kid, and progressively switched to different computers. So it was always about having "let's take a clock apart see how it works and put it back together!" kind of fun, and not wondering "am I good?". If I don't know something, I can usually look it up. Some thing may take time to understand, some things may take a LOT of time to understand, but the general impression is that if I sink enough time into anything, I'll inevitably start to understand it.

    I think this kind of attitude is not correct.
    Any program will ALWAYS have bugs and ugly portions in it.
    The main question is "does it work"? If it does, you can show it. If it doesn't you can also show it. In either case you'll get some recommendations regarding ways to make it better.
     
  8. ptgodz

    ptgodz

    Joined:
    Aug 4, 2016
    Posts:
    99
    Thanks for the responses.

    @FrankenCreations haha thanks man, glad I'm not alone xD

    @AntoineDesbiens That's great to know that it took you a while to until you felt really comfortable with it. I remember when I learnt the what a class actually was and it wasn't until about a week into it that I actually grasped the concept, despite me knowing what it actually was and being able to make instances of a class. Its almost as if something literally clicked one day that I actually understood what I was typing.

    @RichardKain I might actually do that you know. Revisit past projects and try to re code them, that sounds like a really good exercise. Like you said there's only so much time in the world to DL these things bit might really make a difference
     
  9. ptgodz

    ptgodz

    Joined:
    Aug 4, 2016
    Posts:
    99
    Thanks man, This is definitely the best way to think about it. I guess I just feel not very confident with my skills at the moment. Hopefully this changes with time XD
     
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    This is a separate question from good code. I've shown people code from day one. If its bad code, people will offer improvement suggestions. If its good code, people will borrow ideas from it. Remember, your code is not you. People criticizing, slagging or praising your code says nothing about you as a person.

    Does it get the job done? If so, save it and move on. You'll learn more this way then by agonizing over every last detail.

    Not really. I've always been mildly arrogant about my abilities.
     
  11. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    I'd encourage you to keep going. I've seen many people who are new to the programming try to learn how to code (mostly Java, which is a very similar language to C#). And it seems that they usually take more than a few years to become somewhat proficient in the paradigm.

    I'd also suggest that try to do a lot of small projects for practice and read variety of materials available on the internet. Things like object oriented modelling cannot be learned without actually spending quite a lot of time practicing it. And you might need to be aware of certain types of tutorials, because they put too much emphasis on how to make something done and do little in explaining why it does.

    I observed that many of those beginners in programming who struggle have grown a bad habit of skipping the 'why' part and being impatient to search for such tutorials and sample codes that show them 'how' to do some fancy things.

    So, if you find some concept like delegate, as you mentioned, a bit hard to grasp, I'd suggest just taking sufficient time to fully understand it before moving on. There are quite a lot of articles, documentations, tutorials dedicated to make people understand what delegates do, for example, so if you are patient and know how to find them on the internet you can probably teach yourself to become a competent programmer without any formal education these days.
     
    Last edited: Aug 1, 2017
    TeagansDad likes this.
  12. UnityFan18

    UnityFan18

    Joined:
    Jul 4, 2016
    Posts:
    62
    Hello,

    I am in a similar boat as you. Before the summer of 2016, I have never coded in any programming language nor used any game engine. I started following and doing the Unity Learn Tutorials on the website. At first, I was very overwhelmed about scripting. However, the most important thing now for me is to take my time to learn scripting. Taking my time to understand the concept and then doing on hands-on practice for has been very helpful. In addition, because I learn best by doing, I focus on actually practicing coding by doing completing small tasks that I want to accomplish.

    Many times, I have felt frustrated that I haven't mastered scripting or quickly understand several programming concepts. Often, I have felt the desire to quit or give up. That is when I remind myself to be more gentle on myself and to be patient with the learning process. It's awesome that you are coding in the first place, I have used Unity for 1 year, and I am a beginner with coding. However, with time, practice, and plenty of failure, I am learning and getting more and more comfortable with scripting.

    I would say to be patient with yourself and continue to learn about it. Something as complex and comprehensive as a programming language takes a ton of patience, persistence, practice, and time to really master the fundamental concepts.
     
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,146
    This!

    One of the big things for me in my journey to becoming a good programmer was realising that I don't have to write perfect code. In my early days I tried to do things "right" and as a result didn't end up doing very much. As soon as I noticed a flaw I'd try to fix it, which resulted in slow work at best, and didn't necessarily improve quality because I'd be changing designs on the fly and didn't actually have a honed sense of what a "flaw" really was.

    At some point I gave myself permission to write dodgy code as long as it "got the job done". This came with the caveat that I had to learn from the resulting flaws and apply what I learned to future code. I ended up getting stuff "done" faster, I felt better about it because I was no longer aiming for perfection, and the learning cycle ended up being much more effective.

    So if anything, that's my advice. Don't worry about writing "bad" code as long as it's working code. (And I mean properly working, not a cludgy house of cards that dies at the merest change.) If code works properly then don't try to go back and "improve" it unless there's a practical benefit to be gained from it. But make sure that whenever possible*, each piece of code you write is better than the last and doesn't repeat old mistakes.

    * I say "whenever possible" because the reality as a professional/commercial programmer is that sometimes you need to prioritiese short term goals over long term ones, often resulting in pretty rubbish code! The thing is, rubbish code that meets the deadline is practically more beneficial than good code that does not.
     
  14. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,146
    Also, 10 months isn't long. From my perspective, I wouldn't at all be worried about "not getting it" after having put in "only" 10 months across all of a new set of tools, game dev in general and programming in general. I'm not saying that 10 months is a small effort - far from it! It's that there's a heck of a lot to learn there, and 10 months spread between them is really only getting started in the grand scheme of things.
     
  15. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    5,401
    I suggest exposing yourself as much as possible to other people's code. I've learned a lot - not just programming as such but also nifty things that you can do with Unity's API and editor tools - from looking at other people's projects as well as stuff from the asset store.

    Even a couple of years into programming, things like delegates, coroutines - I knew what they were but never really used them until I saw some people's projects and thought "OK, that's definitely a useful thing to use in that situation". And I would make a point of using it in one of my own projects in a similar situation - and sometimes binned it straight after as it caused me more problems than my original approach.

    The problem with other people's code is that it can be very ordinary or even substandard, but still appear much more attractive - it's like if someone makes you a sandwich from whatever has gone stale in your fridge, it tastes 10x better than anything you could make yourself from the same ingredients. Which means that really, you just have to develop a critical view of everything and test it against logic and its success in achieving its intended purpose. Ideally, code should simply work, not cause performance issues to the project as a whole, and be fairly easy to understand. If it ticks these boxes, everything else is irrelevant.

    One more thing I would say is - you say you 'feel like it's a bad way of going about it' - listen to that and try to figure out why you feel that way. Some things in programming are simply unintuitive by nature and you have to accept that, but design-wise it's a red flag and a good opportunity to say "OK what would the ideal architecture/code look like" and then poke around on the internet or in a book for something that you haven't learned about yet, that does it the way you expect that it could be done.
     
  16. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    16,226
    Only slightly when looking at older code, but even then I understand why I wrote it the way I did. My oldest surviving program dates back to the late 90s and has some amusing mistakes, but it was my best and it did the job it needed.

    At least until I ran out of memory for the actual game portion. QuickBASIC had very tight memory limits. :p

    https://pastebin.com/GeyCLJvt
     
  17. Deleted User

    Deleted User

    Guest

    Meh I'm sure my coding sucks, but it seems to work and it doesn't hog performance.. So in the grand scheme of things, couldn't really care. It only becomes an issue if you're applying for a job..
     
    Dave-Carlile likes this.
  18. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    There is an anecdote about pottery students. I have no idea if its true or not, but it certainly fits for programming.

    In the story two pottery classes were given different assignments. The first was told to spend the entire semester working on a single masterpiece. They were to do everything they could to make one perfect piece. The second class was told to make as many pieces of pottery as possible during the semester.

    At the end of the class the one piece pottery group had a single piece of work. It was fairly mediocre, but a passable piece. The many pieces class had made a lot of rubbish at the start, but by the end of the class they were producing master pieces.

    The general take away is that when learning a craft its more efficient to practice many times then it it to get things right once.
     
  19. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    3,517
    If you are trying to lose weight, don't look at the scale every day.

    If you are running a marathon, don't count the miles.

    A watched pot never boils... you get the point.

    Just keep making the process fun.
     
  20. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    Something that irks me about a few of the opinions already stated is yea, you can be a pretty skilled self-taught programmer...

    ...but it usually leads to utterly horrendous habits and mindsets that can be hard to break out of. Everyone else is doing it, so you pick it up. *cough* StackOverflow. Unfortunately I suffered from the same habits as I was self taught through highschool, until I took a CS course and they beat it out of me.

    Partly I think it's just due to being a relatively new field from a global standpoint (computers as we know them were only really made last century), so there's still massive conflict about paradigms, standardisation, convention, the whole OOP vs Procedural thing... Other fields like accounting or biology go back centuries. The roots of agriculture and structural engineering go back millennia.

    </opinion>
     
    Last edited: Aug 1, 2017
    TeagansDad likes this.
  21. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    I actually wouldnt' recommend that.

    A better idea is to stick with books and check code of large apis. For example, I learned what a clean C++ code can look like after getting familiar with Qt framework.

    The reason for my advice is that most of the programs are a horrible eldritch abominations under the hood, so if you try to learn "how things are meant to be done" by looking at other people's project, it is possible that you'll pick up some horrifically bad practices. However, APIs are frequently designed to be as clean as possible, so they would serve as a better example.

    You're still supposed to be able to understand code written by other people, but you shouldn't use it as a source of inspiration, or anything like that.
     
    Scabbage likes this.
  22. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    larku, TeagansDad and mysticfall like this.
  23. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    5,401
    I recommended it for a few reasons.

    1) As a self-taught programmer, one thing you don't develop very well is the ability to deal with other people's code. At least for me, I ended up with too much of a dependence on having everything that I worked on done exactly the way I wanted to do it. When I first started working on others projects, I spend too much time refactoring code that didn't actually need to be.

    2) This is the main one for me: I find the idea of learning random bits and pieces of programming unpleasant, boring and ultimately the information is very difficult to retain for any reasonable period after learning it - especially when you are your own (rudderless) teacher, and you have much more dependably productive ways to spend your time (like working on a problem that exists). So learning by looking over someone's project is quite a good way to be exposed to a range of things you probably wouldn't have otherwise known that you should have learned by now, in a real setting.

    3) If one is really interested in getting a better idea of one's own skill level relative to everyone else, the best way to figure it out is to look at what the quality of other people's work is - which is what you automatically get exposed to in a workplace. Especially if you're a completely self-taught programmer interested in freelancing, it can be useful to do this.

    Ultimately, your biggest weapon as a programmer is the ability to learn fast from a good textbook (once you have enough experience to know where you need to look to solve a particular problem), but in the beginning, I think exposure to other people's code is an under-valued experience for self taught programmers.
     
  24. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    Opinion:
    This is based on dangerous assumption that other people are significantly better than you. In my opinon, a programmer will probably reach a "knowledge plateau" in a 5 or so years of working, and that's the level at which pretty much everybody is. Once you're there, there are no gurus to enlighten you and nobody will be answering your questions. You can specialize in some tech, or can try to grab wider array of skills, but in general that is it. You won't ever receive same level of advancement of your knowledge as you did when you learned programming.

    The worst thing that can happen to people at this stage is subscribing to some sort of programming ideology and turning it into a cargo cult. There are many such cults, for example "100% test coverage" and even previously used SOLID method can be treated as religion and abused to make code less readable, when it is taken to an extreme.

    I saw some... truly horrific code written by other people, and as a result, I would recommend to avoid using code written by other people in a sense that while you should be able to make sense out of it, you almost never should use it as an example to follow, and stick with books, libraries and apis instead. Random projects written by some John Doe are often S*** in terms of code quality, and picking those habits would be a bad idea. With a book you'll at least have higher chance that it is written by a dude that spent last 40 years of his life on this particular language.
     
  25. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    API's are also written by others. ;) There are some horrible written APIs out there. So I wouldn't see that as any better as any other code written by others.

    And, never ever use SDKs on the asset store as any reference! (They are often written by C people that dont understand C# at all)

    About the five year statement, sure maybe not as a plain programmer, but you can surly go further as a system architect etc. The standard dev mostly only focus on a feature at a time. The architect on the entire system and its maintainability
     
    mysticfall likes this.
  26. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    That's a rough idea, and not a strict rule.

    The general idea is, when people start out programming, they think that there us a lot to learn and the world is full of gurus. Later you sorta realize that so called gurus are actually people who are just mediocre at their work at best, true gurus are probably hiding somewhere without ever accessing internet to share their wisdom, and you're on your own.

    Speaking of "5 principles everybody should know"... when somebody provides such principles it is critically important that they explain WHY they think such principles are supposed to be good.
    If they can't explain, most likely you're dealing with a cargo cult.

    I prefer to use more open-ended principles that do not restrict you to specific methodic.

    For example: "Programmer's job is to implementa feature while minimizing development time, development cost, maintenance cost, adhering to specification and keeping the implementation efficient". This covers pretty much everything withotu any wiggle room. You can go to "lalalala land" forever redisining object hierarchies till they're "beautiful", you can't be sloppy (because it'll increase maintenance cost), etc.
     
  27. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    5,401
    Not at all. The biggest realization I had when I looked at other people's projects (especially some kits from the store) was that I could write much more organized and efficient code than I thought.

    I definitely do not recommend assuming that everyone is better, when you look at others code the idea is to look at it critically. Sometimes its a snapshot from the mind of a well-organised person who knows more than you do. Sometimes it's the opposite.

    I think my main point is that, if you're self-taught, it's a bad idea to try to set up some kind of self-conducted long-term university course where you attempt to be the teacher, the student, and the student's peers simultaneously. Learning by trial and error to fix a real problem or complete a real project is a million times better and faster, and exposure to other people's work is not only useful (to learn the good and the bad), but it helps drive motivation by making you feel connected to peers.

    Once you reach a certain point, I do agree it becomes not very useful to pay much attention to how other people do things. But that is because you already have the experience of dealing with other people's code, and your beliefs in your own skill are justified.
     
  28. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    In my opinion, if you always find it worthless to study other people's code, it could simply mean that you are looking at wrong people to learn from.

    These days, real 'gurus' don't really hide anywhere, but often found to be busy actively writing technical articles, or doing open source projects, and etc. It's simply a matter of knowing where to look.

    That sounds more like what a non-technical manager might think a good programmer does, not any concrete, useful design principle that actual programmers can follow, like SOLID principles, for instance.
     
    Last edited: Aug 1, 2017
  29. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    931
    The Evolution of a Software Engineer
     
    derf likes this.
  30. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    Comments are the evil on this earth. Most comments are of this fashion.

    Code (CSharp):
    1. //Save customer to database
    2. repository.Save(customer);
    99.9% of all comments are not maintained so they are not even correct and upto date to the signature of said code. I hate comments, comments are evil.
    Good code is self explaining through good cohesion and decoupling, method names, etc

    Comments are a way to try to fix bad code, I hate comments, comments are evil
     
    Last edited: Aug 1, 2017
  31. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    :D
    Reminds me of this:
    Code (csharp):
    1.  
    2.  
    3. float Q_rsqrt( float number )
    4. {
    5.    long i;
    6.    float x2, y;
    7.    const float threehalfs = 1.5F;
    8.  
    9.    x2 = number * 0.5F;
    10.    y  = number;
    11.    i  = * ( long * ) &y;                    
    12.    i  = 0x5f3759df - ( i >> 1 );               // what the f***?
    13.    y  = * ( float * ) &i;
    14.    y  = y * ( threehalfs - ( x2 * y * y ) );
    15. //    y  = y * ( threehalfs - ( x2 * y * y ) );
    16.  
    17.    return y;
    18. }
    19.  
     
    hippocoder and AndersMalmgren like this.
  32. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,406
    oh, and log everywhere, dont get me started on log everywhere

    like

    Code (CSharp):
    1. try
    2. {
    3.    //Save customer to database
    4.    repository.Save(customer);
    5. }
    6. catch(e)
    7. {
    8.    //Log if not possible to save customer
    9.     logger.Error(e, "Could not save customer");
    10.    return false;
    11. }
    12.  
    13. return true;
    This code give zero advantage over generic logging at a top tier level. And that bool, nobody listens to it anyway. Fail early, fail hard, recover gracefully
     
  33. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    derf and Aiursrage2k like this.
  34. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,244
    Yeah. Before I entered UNI and saw my mentors' code. Been feeling pretty good about my code since then.
     
  35. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    Plus when we engineers mess up, people die. There is a brutal sort of natural selection that has honed out most of the bad ideas.

    Bad code, on the other hand, normally had no appreciable consequences outside of the decs that work with it. (By the same token the rules for code governing high consequence situations gets really strict really fast.)
     
    Ryiah likes this.
  36. DominoM

    DominoM

    Joined:
    Nov 24, 2016
    Posts:
    460
    If I read my old code after a year or so and can quickly understand what it's doing, then it's good code in my book. I may have written it differently now, sometimes there's ways to make it better, but as long as it did what it needed I wouldn't think of it as bad. Even doing the wrong thing can sometimes turn into something good.
     
    neginfinity and Kiwasi like this.
  37. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,712
    I think that once code gets even slightly complicated, everyone will have an opinion that it's either good or bad. I just think that my code is usually either slightly worse or a lot worse than someone else's.

    I beg to differ on the "comments are evil" opinion. I think comments are great for coming back to an old project. If I come back to a year-old project, I will have forgotten almost everything about how I wrote it. Comments really help me understand what I intended to do in that function, why am I multiplying "x" by "y" and why I decided to write "what the f***" instead of what that line actually does :). If you're reading your comments daily to understand what's going on, you're doing it wrong, but if you've written comments once and come back to them a long time later, you're using them as intended.

    Just my 2 cents
     
  38. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,146
    To me that sounds like you're using comments effectively, which does make them useful.

    You're commenting intent and reason, answering the "why?" questions. This is really useful, because it's stuff that you can't necessarily tell by just reading the code itself.

    On the flip side, I find that a lot of coders instead comment the "what?" questions, which basically means they're writing their code in two different languages at once - their programming language and English. In that case the English isn't telling you anything that the code isn't also telling you. It just adds maintenance and opportunities for error (because you need to make sure both things line up with each other) without adding meaning or useful information.

    In short, comments should be useful, in a way that results in less work for readers and minimal work for the writer.

    Also, while the often cited example is "I don't recognise my own code 6 months after I wrote it", keep in mind that in many cases the audience for your comments is other programmers on your team rather than a future self. Keep that in mind when you write the comments - why might they be reading them, and if they are reading them what do they need to know?
     
    DroidifyDevs and Kiwasi like this.
  39. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,822
    there are a lot of different kinds of comments.

    Code (CSharp):
    1.    //Save customer to database
    2.    repository.Save(customer);
    I don't think these are usually that bad. Most of the time these kinds of comments are from newbies (or domain newbies). Example:

    Code (csharp):
    1. // get the direction from b to a
    2. Vector3 d = (a - b).normalized;
    This is also an obvious 1 liner, but for people who really aren't familiar with vectors, it can be helpful to have a comment that literally steps through the code statement by statement.

    Code (csharp):
    1. //---------------------------------------
    2. //-------- [Description of task]
    This kind of comment is sort of a block header. Useful for delineating dense code for quick visual scan.

    _____________

    In general, I would say that comments are usually an indication that the developer is usually struggling a bit with the problem at hand.

    Code with a lot of comments is usually code that was very difficult for the author to write.

    It's usually true that you will find a lot of comments near code that's problematic, but comments in these cases are usually a side effect of the developer struggling with the subject, not the other way around. In other words, your code does not improve with fewer comments.
     
    Last edited: Aug 2, 2017
  40. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    13,146
    I'm going to be contrary here...

    The first comment tells you nothing that the line of code doesn't. The line literally says "Repository, Save this customer", but in C# instead of English. What benefit does having the English next to it have?

    For the second one, if you need to explain the math then surely you also need to explain why it's normalized? If not, then why not something like:
    Code (csharp):
    1. Vector3 direction = (destination - origin).normalized;
    The main thing that jumps out at me in there is that "d", "a" and "b" are names that provide no description and meaning. If you use meaningful/descriptive names then your code is "self documenting" and you can afford to use comments a lot less.
     
    AndersMalmgren likes this.
  41. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    Some comments are evil. Certainly a comment on every line is. I generally take the assumption that anyone reading my code is able to program and is familiar with the environment my code runs in. So there isn't a need to write out what every line does. The target audience for my comments is not a beginning programmer on their first day using Unity.

    Comments add additional workload to create and maintain. Every line comments add to the information a reader has to parse. First they read the comment, then they read the code. Then they check if they say the same thing. If they don't they have to waste time wondering which the developer intended. They also tend to hide places where the comments really are important.

    On the other hand there are plenty of things my code doesn't say. And that stuff can be useful to anyone reading my code. Generally I try and comment anything that will reduce the cognitive workload for a reader in the future.

    For example 'A* algorithm' or 'factory pattern' as a comment would instantly ground the reader, without them having to parse all of the code. And on the off chance they are not familiar with the pattern, they can look it up. Its also useful to have general overviews of what a complex class is responsible for at the top of the script.

    Other times I will use comments to break up long methods. For example this:

    Code (CSharp):
    1. void MakeWater (){
    2.  
    3.     // Calculate the water size
    4.     ManyLinesOfStuff
    5.     ...
    6.  
    7.     // Generate the GameObjects
    8.     SomeLongLoop
    9.     ...
    10.    
    11.     // Set up for physics interations
    12.     MoreLinesAndLoops
    13.     ...
    14. }
    With this method you can just parse the comments, and get a decent idea of what the method is doing internally. (I've seen people argue that this should be separated into multiple methods, and you can use the method name in place of my comment. But I'm not a big fan of this argument. If a method is only designed to be called from a single context, it probably doesn't deserve to be its own method. Checking to make sure the method is only called from one context adds to the readers cognitive load)

    I'll also point out weaknesses in my code. For example 'this section would be brittle if the world size were to be dynamic instead of fixed'. Or even 'this section occasionally throws error xxx for unknown reasons'.

    TL;DR: If a comment reduces the overall workload, write it. If a comment increases the overall workload, don't write it.
     
    frosted likes this.
  42. mysticfall

    mysticfall

    Joined:
    Aug 9, 2016
    Posts:
    649
    As to whether or not comments are useful, I think it need to differentiate between those used in documenting the API (like Javadoc, or those start with /// in C#) and the rest of the random comments inside code blocks.

    Even though I have to admit that I'm usually a bit too lazy to thoroughly comment my code, I believe the former type of comments are recommended, and it is considered a good practice to write comments for all public and protected types and their members, in general.

    On the other hand, I agree with those people who say that any piece of code should be self explanatory, and normally one shouldn't have much difficulty in understanding a well designed API by reading its reference documentation (which is often generated by the above mentioned type of comments), so looking into its source code is often unnecessary to see the intent of any non-private class or its members, and their implementation shouldn't be too long or obscure to understand without extensive comments.

    And it's also one of the reason why spending sometime to learn common design patterns or principles can be a good idea, since it can help people to communicate with their code without writing a lot of comments that explain their intent. For instance, when a class is named XXXFactory or XXXDecorator, one can easily understand what they are suppose to do or what kind of methods they contain just by reading their names, if one understands the patterns that are implied in such a convention.

    There might be certain constraints or contract that is difficult to grasp by reading the source code, but if it's something that the invoker should know of, it better be explained in the API documentation, rather than in a statement level comments that only those who have access to the source can read. Or better, such constraints or contracts can be written as a test case instead, which is often considered as another type of documentation (which is why most of the testing frameworks provides a domain specific language to write tests in a descriptive manner).

    In my opinion, the only occasion that calls for non-API (statement level) comments is when one needs to write some temporary code to workaround certain hard to expect limitations or erratic behaviors of an external library or a platform. In that case, it might be a good idea to create a ticket in an issue tracker about the problem, and write a short comment with a reference to the issue, so that later such workarounds can be replaced or removed when the underlying problem cease to exist.
     
    Last edited: Aug 2, 2017
  43. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,712
    WTF did I just read...

    Code with comments (by comments I mean smart comments, not comments converting c# line-by-line to English) shows that the programmer was thinking about both his future self and other team members.

    For example, let me dump this code on you:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SocialPlatforms;
    3. using UnityEngine.UI;
    4. using System.Collections.Generic;
    5. using System.Collections;
    6. using UnityEngine.Analytics;
    7. using UnityEngine.Advertisements;
    8. //using GooglePlayGames;
    9. using System;
    10.  
    11. public class PlayerController : MonoBehaviour {
    12.  
    13.     public Rigidbody PlayerRigid;
    14.     public GameObject ButtonControls;
    15.     public GameObject DeathPanel;
    16.     public GameObject SettingsButton;
    17.     //how much you want to jump, ex 250
    18.     public int JumpForce;
    19.     //average velocity AUTO-CALCULATED
    20.     public float AvgVelocity;
    21.     //how much more to jump when bouncing
    22.     public float BouncerFactor;
    23.     //distance from player to ground
    24.     public float DistanceFromGround;
    25.     //how much friction when rolling on groud
    26.     public float GroundFrictionAmount;
    27.     //how much you want to push on the X MAXIMUM, ex 200
    28.     public float XForceMax;
    29.     //how much you want to really move
    30.     //public float XForceReal;
    31.     //this is how much you want to bounce, ex 45
    32.     public int BounceForceFactor;
    33.     //this is automatically calculated, do NOT set it. At start it can NOT be zero
    34.     public float BounceForce = 1;
    35.     //this is when there is too much BounceForce
    36.     public float BounceForceOverMax;
    37.     //this is the minimum force needed to start a bounce, preventing infinite bouncing
    38.     public float BounceForceMin;
    39.     //this is to lower amount of force of bounce if ball is too powerful
    40.     public float BounceForceLimiter;
    41.     //this is when the ball is too high, set it lower than what you think is too high
    42.     public float TooHighY;
    43.     public float OvejumpProtectionAmount;
    44.     //this is when to limit the ball's jump speed, ex 10
    45.     public float MaxYVelocityAmount;
    46.     public bool MoveRight;
    47.     //distance text
    48.     public Text DistanceText;
    49.     public Image DistanceFillImage;
    50.     public float Distance;
    51.     public float DistanceRecord; //get from GOOGLE, NOT PLAYERPREFS
    52.     public float DistanceFillAmount;
    53.     public Vector3 OrigPosition;
    54.     //these are forces we use with BUTTONS
    55.     public int ButtonForceSides = 150;
    56.     public int ButtonForceUp = 300;
    57.     //this is position of checkpoint to revive at
    58.     public Vector3 Checkpoint;
    59.     //this is for ads
    60.     public GameObject AdFail;
    61.     public GameObject GooglePromo;
    62.     public Text GooglePromoText;
    63.     public string DeathObjectName;
    64.     //don't forget to change GooglePlay.cs's ID as well
    65.     public string LeaderboardID;
    66.     public float hue, S, V;
    67.     public Color GreenColor;
    68.     public string DeathEffects = "Death Effects";
    69.     public Text DeathText;
    70.     public float EffectLength;
    71.     public GameObject Explosion;
    72.     public AudioSource SliceSound;
    73.     public AudioSource ExplosionSound;
    74.     private GameObject GravityObject;
    75.     public Text AnnounceText;
    76.     public string SavePlayerPrefName;
    77.     private int TimesSampled;
    78.     private float TotalVelocity;
    79.     // Use this for initialization
    80.     void Start ()
    81.     {
    82.         //save original position
    83.         DistanceRecord = PlayerPrefs.GetFloat(SavePlayerPrefName);
    84.         //PlayGamesPlatform.Activate();
    85.         OrigPosition = transform.position;
    86.         if (PlayerPrefs.GetInt("AskAboutGoogle1stTime") == 0)
    87.         {
    88.             //ask to log in
    89.             GooglePromo.SetActive(true);
    90.             Debug.Log("Asking to log in");
    91.         }
    92.  
    93.         if (PlayerPrefs.GetInt("PlayerLoggedInGoogle") == 1)
    94.         {
    95.             //player has shown interest in logging in, so do it!
    96.             GetPlayerDataWithUnitySocial();
    97.             Debug.Log("Player has logged in before, so loggin in now");
    98.         }
    99.  
    100.         if (PlayerPrefs.GetInt("PlayerLoggedInGoogle") == 2)
    101.         {
    102.             //don't log in, this player isn't too interested
    103.             GooglePromo.SetActive(false);
    104.             Debug.Log("Player declined log in");
    105.         }
    106.     }
    107.  
    108.     void GetPlayerDataWithUnitySocial()
    109.     {
    110.         Debug.Log("Trying to get player data...");
    111.         Social.localUser.Authenticate(success =>
    112.         {
    113.             if (success)
    114.             {
    115.                 GooglePromoText.text = "Thanks! You're logged in :)";
    116.                 Debug.Log("Authentication successful");
    117.                 string userInfo = "Username: " + Social.localUser.userName +
    118.                     "\nUser ID: " + Social.localUser.id +
    119.                     "\nIsUnderage: " + Social.localUser.underage;
    120.                 Debug.Log(userInfo);
    121.                 DistanceRecord = PlayerPrefs.GetFloat(SavePlayerPrefName);
    122.                 Debug.Log("DistanceRecord set from Google!");
    123.                 GooglePromo.SetActive(false);
    124.             }
    125.  
    126.             else
    127.             {
    128.                 //if can't log in, use local high score
    129.                 DistanceRecord = PlayerPrefs.GetFloat(SavePlayerPrefName);
    130.                 GooglePromoText.text = "Oh no, login failed! If you don't have internet, please connect and try again.";
    131.                 Debug.Log("Unity-social login FAIL");
    132.             }
    133.  
    134.             Social.LoadScores(LeaderboardID, scores => {
    135.                 if (scores.Length > 0)
    136.                 {
    137.                     Debug.Log("Got " + scores.Length + " scores");
    138.                     string myScores = "Leaderboard:\n";
    139.                     foreach (IScore score in scores)
    140.                     {
    141.                         myScores += "\t" + score.userID + " " + score.formattedValue + " " + score.date + "\n";
    142.                         if (Social.localUser.id == score.userID)
    143.                         {
    144.                             Debug.Log("This user's score is: " + score.formattedValue);
    145.                             //since we're connected, let's pull Google's high score instead of local one
    146.                             DistanceRecord = Convert.ToSingle(score.formattedValue);
    147.                             //also, let's update our local high score to match Google's
    148.                             PlayerPrefs.SetFloat(SavePlayerPrefName, DistanceRecord);
    149.                             Debug.Log("Updated local distance record from Google!");
    150.                             return;
    151.                         }
    152.                     }
    153.                     Debug.Log(myScores);
    154.                 }
    155.  
    156.                 else
    157.                 {
    158.                     Debug.Log("No scores loaded");
    159.                     //if nothing on leaderboard, use local score and hope more people download this s***
    160.                     DistanceRecord = PlayerPrefs.GetFloat(SavePlayerPrefName);
    161.                 }
    162.             });
    163.         });
    164.         //post local score in case the player had a better offline score
    165.         //google should take care of the rest
    166.         DistanceRecord = Mathf.RoundToInt(PlayerPrefs.GetFloat(SavePlayerPrefName));
    167.         Social.ReportScore(Mathf.RoundToInt(DistanceRecord), LeaderboardID, (bool success) =>
    168.         {
    169.         });
    170.     }
    171.  
    172.     public void ShowLeaderboard()
    173.     {
    174.         Social.ShowLeaderboardUI();
    175.     }
    176.  
    177.     // Update is called once per frame
    178.     void Update ()
    179.     {
    180.         //Debug.Log("Player X velocity: " + PlayerRigid.velocity.x);
    181.         //if ball jumps too high
    182.         if (DistanceFromGround > TooHighY)
    183.             {
    184.             //apply a small push towards the ground
    185.                 InitiateOverjumpProtection();
    186.             }
    187.         //raycast distance to ground
    188.         RaycastHit hit;
    189.         Ray downRay = new Ray(this.transform.position, Vector3.down);
    190.         if (Physics.Raycast(downRay, out hit))
    191.         {
    192.             //get distance to groud
    193.             DistanceFromGround = hit.distance;
    194.         }
    195.  
    196.         if (PlayerRigid.velocity.y >= MaxYVelocityAmount)
    197.         {
    198.             //remove its velocity
    199.             PlayerRigid.velocity = new Vector3(PlayerRigid.velocity.x, 0, PlayerRigid.velocity.z);
    200.             Debug.Log("Y velocity limited");
    201.         }
    202.         CalcDistanceText();
    203.         CalcAvgVelocity();
    204.  
    205.         if (Input.GetKeyDown("a"))
    206.         {
    207.             LeftButton();
    208.         }
    209.  
    210.         if (Input.GetKeyDown("d"))
    211.         {
    212.             RightButton();
    213.         }
    214.  
    215.         if (Input.GetKeyDown("space"))
    216.         {
    217.             JumpUp();
    218.         }
    219.     }
    220.  
    221.     void OnCollisionEnter(Collision collision)
    222.     {
    223.         //reset the bounce force limiter
    224.         BounceForceLimiter = 1;
    225.         //calculate how much bounce force to add based on the limiter and bounce magnitude
    226.         BounceForce = BounceForceFactor * collision.relativeVelocity.magnitude * BounceForceLimiter;
    227.         if (BounceForce > BounceForceOverMax)
    228.         {
    229.             //if too much then limit bounce
    230.             LimitBounce();
    231.             //now that we've limited the bounce force, use it
    232.             PlayerRigid.AddForce(Vector3.up * BounceForce);
    233.             return;
    234.         }
    235.  
    236.         if (BounceForce > BounceForceMin)
    237.         {
    238.             //if greater than minimum bounce force value. Do this so it
    239.             //doesn't bounce forever
    240.             PlayerRigid.AddForce(Vector3.up * BounceForce);
    241.         }
    242.  
    243.         if (collision.gameObject.CompareTag("Death"))
    244.         {
    245.             //if it hits something bad (flames, spikes etc...)
    246.             KillPlayer();
    247.         }
    248.     }
    249.  
    250.     void OnTriggerEnter(Collider collision)
    251.     {
    252.         //again kill player, just if it hits a trigger
    253.         //DEATH just deactivates. Add other tags for death effects.
    254.         if (collision.gameObject.CompareTag("Fire"))
    255.         {
    256.             //show fire effect, wait, then die
    257.             DeathText.text = "Roasted!";
    258.             StartCoroutine(ShowDeathEffect());
    259.             Explosion.SetActive(true);
    260.             ExplosionSound.Play();
    261.         }
    262.  
    263.         if (collision.gameObject.CompareTag("NoGravity"))
    264.         {
    265.             PlayerRigid.AddForce(Vector3.up * 30);
    266.             Physics.gravity = new Vector3(0, -3F, 0);
    267.             StartCoroutine(TimeWithGravity());
    268.             GravityObject = collision.gameObject;
    269.             collision.gameObject.SetActive(false);
    270.             AnnounceText.text = "Low gravity!";
    271.             StartCoroutine(Announce(5));
    272.         }
    273.  
    274.         if (collision.gameObject.CompareTag("Impale"))
    275.         {
    276.             //show fire effect, wait, then die
    277.             EffectLength = 1;
    278.             StartCoroutine(ShowDeathEffect());
    279.             DeathText.text = "Impaled!";
    280.             PlayerRigid.constraints = RigidbodyConstraints.FreezeAll;
    281.         }
    282.  
    283.         if (collision.gameObject.CompareTag("Death"))
    284.         {
    285.             KillPlayer();
    286.             DeathText.text = "Unknown death!";
    287.         }
    288.  
    289.         if (collision.gameObject.CompareTag("Bullet"))
    290.         {
    291.             KillPlayer();
    292.             DeathText.text = "Shot!";
    293.         }
    294.  
    295.         if (collision.gameObject.CompareTag("Smash"))
    296.         {
    297.             DeathText.text = "Smashed!";
    298.             KillPlayer();
    299.         }
    300.  
    301.         if (collision.gameObject.CompareTag("Zap"))
    302.         {
    303.             DeathText.text = "Electrocuted!";
    304.             KillPlayer();
    305.         }
    306.  
    307.         if (collision.gameObject.CompareTag("Slice"))
    308.         {
    309.             DeathText.text = "Sliced!";
    310.             SliceSound.Play();
    311.             KillPlayer();
    312.         }
    313.  
    314.         //if player hits bounce point, bounce the player
    315.         if (collision.gameObject.CompareTag("Bouncer"))
    316.         {
    317.             StartCoroutine(BounceAllower());
    318.             PlayerRigid.AddForce(Vector3.up * JumpForce * BouncerFactor);
    319.         }
    320.  
    321.         if (collision.gameObject.CompareTag("BouncerExtra"))
    322.         {
    323.             StartCoroutine(FasterTime());
    324.             Time.timeScale = 1.5f;
    325.             AnnounceText.text = "Faster time!";
    326.             StartCoroutine(Announce(15));
    327.         }
    328.  
    329.         if (collision.gameObject.CompareTag("TriggerCube"))
    330.         {
    331.             Checkpoint = collision.transform.position;
    332.             DeathObjectName = collision.gameObject.GetComponent<UnitStopper>().UnitParent.name;
    333.         }
    334.     }
    335.  
    336.     void OnCollisionStay(Collision collision)
    337.     {
    338.         //add optional ground friction
    339.         PlayerRigid.drag = GroundFrictionAmount;
    340.     }
    341.  
    342.     public void JumpUp()
    343.     {
    344.         //make the ball jump up ONLY if it isn't too high
    345.         if (DistanceFromGround < TooHighY)
    346.         {
    347.             PlayerRigid.AddForce(Vector3.up * JumpForce);
    348.         }
    349.     }
    350.  
    351.     public void JumpX()
    352.     {
    353.         //move left-right
    354.         //PlayerRigid.velocity = Vector3.zero;
    355.         if (MoveRight)
    356.         {
    357.             PlayerRigid.AddForce(Vector3.right * ButtonForceSides);
    358.         }
    359.  
    360.         else
    361.         {
    362.             PlayerRigid.AddForce(Vector3.left * ButtonForceSides);
    363.         }
    364.     }
    365.  
    366.     void LimitBounce()
    367.     {
    368.         //limit bounce if needed
    369.         BounceForceLimiter = (BounceForceOverMax / BounceForce);
    370.         BounceForce = BounceForce * BounceForceLimiter;
    371.     }
    372.  
    373.     void InitiateOverjumpProtection()
    374.     {
    375.         //this protects the ball from jumping too high, ex out of the screen's viewing range
    376.         //however it does add force down, which is why we have LimitBounce too
    377.         //PlayerRigid.AddForce(Vector3.up * OvejumpProtectionAmount * -1);
    378.         //Debug.Log("OverjumpProtection activated");
    379.     }
    380.  
    381.     void KillPlayer()
    382.     {
    383.         this.gameObject.SetActive(false);
    384.         DeathPanel.SetActive(true);
    385.         ButtonControls.SetActive(false);
    386.         SettingsButton.SetActive(false);
    387.         //now let's get some data
    388.         Analytics.CustomEvent("gameOver", new Dictionary<string, object>
    389.         {
    390.             { "DeathUnit", DeathObjectName},
    391.         });
    392.         Debug.Log("Analyzed, died at: " + DeathObjectName);
    393.         if (Distance > PlayerPrefs.GetFloat(SavePlayerPrefName))
    394.         {
    395.             //save new distance
    396.             PlayerPrefs.SetFloat(SavePlayerPrefName, Distance);
    397.             //report to Google
    398.             int HighScore = Mathf.RoundToInt(PlayerPrefs.GetFloat(SavePlayerPrefName));
    399.             Social.ReportScore(HighScore, LeaderboardID, (bool success) =>
    400.             {
    401.             });
    402.                 Debug.Log("New distance record saved! " + PlayerPrefs.GetFloat(SavePlayerPrefName));
    403.         }
    404.     }
    405.  
    406.     public void RevivePlayer()
    407.     {
    408.         ShowRewardedAd();
    409.     }
    410.  
    411.     public void ShowRewardedAd()
    412.     {
    413.         if (Advertisement.IsReady("rewardedVideo"))
    414.         {
    415.             var options = new ShowOptions { resultCallback = HandleShowResult };
    416.             Advertisement.Show("rewardedVideo", options);
    417.         }
    418.     }
    419.  
    420.     void CalcDistanceText()
    421.     {
    422.         //just in-game to calculate how far the ball went
    423.         Distance = (this.transform.position.x - OrigPosition.x) * -1;
    424.         Distance = Mathf.RoundToInt(Distance);
    425.         //get DistanceRecord on start, getting it from PlayerPrefs is too slow for Update
    426.         if (Distance > DistanceRecord)
    427.         {
    428.             DistanceText.text = "New record: " + Distance;
    429.             DistanceText.color = GreenColor;
    430.         }
    431.         else
    432.         {
    433.             DistanceText.text = "Distance: " + Distance;
    434.         }
    435.         //now for the bar
    436.         DistanceFillAmount = Distance / DistanceRecord;
    437.         DistanceFillImage.fillAmount = DistanceFillAmount;
    438.     }
    439.  
    440.  
    441.     IEnumerator BounceAllower()
    442.     {
    443.         float origYMax = MaxYVelocityAmount;
    444.         MaxYVelocityAmount = 99;
    445.         yield return new WaitForSeconds(1);
    446.         MaxYVelocityAmount = origYMax;
    447.     }
    448.  
    449.     //on-screen sontrol buttons
    450.     public void LeftButton()
    451.     {
    452.         MoveRight = false;
    453.         JumpX();
    454.     }
    455.  
    456.     public void RightButton()
    457.     {
    458.         MoveRight = true;
    459.         JumpX();
    460.     }
    461.  
    462.     public void JumpButton()
    463.     {
    464.         JumpUp();
    465.     }
    466.  
    467.     //this is to show and award the ad
    468.     private void HandleShowResult(ShowResult result)
    469.     {
    470.         switch (result)
    471.         {
    472.             case ShowResult.Finished:
    473.                 Debug.Log("The ad was successfully shown.");
    474.                 FinishReviving();
    475.                 break;
    476.             case ShowResult.Skipped:
    477.                 Debug.Log("The ad was skipped before reaching the end.");
    478.                 break;
    479.             case ShowResult.Failed:
    480.                 Debug.LogError("The ad failed to be shown.");
    481.                 break;
    482.         }
    483.     }
    484.  
    485.     void FinishReviving()
    486.     {
    487.         PlayerRigid.velocity = Vector3.zero;
    488.         this.transform.position = Checkpoint;
    489.         this.gameObject.SetActive(true);
    490.         DeathPanel.SetActive(false);
    491.         ButtonControls.SetActive(true);
    492.         SettingsButton.SetActive(true);
    493.     }
    494.  
    495.     public void LogInToGoogle()
    496.     {
    497.         GooglePromoText.text = "Thanks! Now logging in...";
    498.         GetPlayerDataWithUnitySocial();
    499.         PlayerPrefs.SetInt("PlayerLoggedInGoogle", 1);
    500.         Debug.Log("Player wants to log into Google");
    501.     }
    502.  
    503.     public void DeclineGoogleLogIn()
    504.     {
    505.         PlayerPrefs.SetInt("AskAboutGoogle1stTime", 1);
    506.         PlayerPrefs.SetInt("PlayerLoggedInGoogle", 2);
    507.         GooglePromo.SetActive(false);
    508.         Debug.Log("Player doesn't want to log into Google. Ouch!");
    509.     }
    510.  
    511.     void CalcAvgVelocity()
    512.     {
    513.         TimesSampled++;
    514.         TotalVelocity += PlayerRigid.velocity.x;
    515.         if (TimesSampled == 8)
    516.         {
    517.             AvgVelocity = TotalVelocity / TimesSampled;
    518.             TotalVelocity = 0;
    519.             TimesSampled = 1;
    520.         }
    521.     }
    522.  
    523.     IEnumerator ShowDeathEffect()
    524.     {
    525.         yield return new WaitForSeconds(EffectLength);
    526.         KillPlayer();
    527.     }
    528.  
    529.     IEnumerator TimeWithGravity()
    530.     {
    531.         yield return new WaitForSeconds(5);
    532.         Physics.gravity = new Vector3(0, -9.8F, 0);
    533.         GravityObject.SetActive(true);
    534.     }
    535.  
    536.     IEnumerator FasterTime()
    537.     {
    538.         yield return new WaitForSeconds(15);
    539.         Time.timeScale = 1;
    540.     }
    541.  
    542.     IEnumerator Announce(int AnnounceTime)
    543.     {
    544.         AnnounceText.gameObject.SetActive(true);
    545.         yield return new WaitForSeconds(AnnounceTime);
    546.         AnnounceText.gameObject.SetActive(false);
    547.     }
    548. }
    549.  
    I wrote that a long time ago as a control script for a side-ways ball bouncing game (for the project "Closest I ever came to publishing something" in my signature). It's not great code, I hope I've improved a lot since today I'd write it differently (seriously, why am I putting advertising & leaderboard service calls in a player controller). But my point is, if I didn't comment anything (taking your opinion that commenting code is a sign of weakness), after spending a few minutes you'd have a general idea of what's going on. However, with my comments, you have a better understanding of what I intended without having to spend time trying to understand what is " InitiateOverjumpProtection();" or why on Line 315 I'm not killing the player. This is especially important if someone is debugging and they're looking for something "fishy" in my code.

    That code is also full of "evil comments", where I was a little over my head back then and sometimes did resort to converting c# to English for no reason. So I'd say that code has both good and bad comments, but I'd rather have over-commented code than under-commented code.
     
    Last edited: Aug 2, 2017
  44. TonicMind

    TonicMind

    Joined:
    Nov 9, 2014
    Posts:
    1,211
    Let us remember that "good" and "bad" are subjective terms...

    I understand that there are some things which may guide you to determine whether something (say, code) is good or is bad. Perhaps it would be a good idea to think hard on why you think your code might be so.

    Go beyond the notion of "it doesn't look like his/hers", perhaps efficiency is most important to you, conciseness, or readability. Maybe its two or out of those three or seven out of 10 other metrics.

    I have never heard anything of this sort of story.

    Fascinating, and there is definitely something to be learned here...

    Found myself wishing I'd done more projects at this point recently. I've not worked on the mouse flight project much since May, haven't been feeling well and have been pretty busy.

    I'm one of those "perfectionists". I want my project to get "finished", or at least be something other than just a prototype. That said I probably bit off more than I can chew. I've been thinking about how those things you find yourself thinking semi-subconsciously (is that possible??) all the time are probably things that need to change.

    Things like "it needs to have more features" or "this needs polish"...

    And ah, regret. Such a sad and bitter feeling. Find myself regretting/retrospecting a lot lately... which I believe is helpful (mainly the retrospection) because it gives you perspective and allows you to learn from past mistakes.

    Just imagine how awesome my github would look if I had done a bunch of smallish games instead of this giant one. Now imagine if looking forward I set out to avoid making that mistake again. How far along might I be?

    I'm retaking a class right now and have uploaded about five different labs to my github. I worked for hours a day for most of July to get them completed... maybe that should be my goal. A new project completed every week or two. In fact make that every month, giving a bit more time to complete said game (or project). It required some sacrifice just trying to get those labs done... but boy was I committed. Like never before, really.
     
  45. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,734
    My wife is an art teacher. I'm not sure where she found the story, but she has referred to it a lot in relation to her students. It seems for the most part that making lots of art is more productive then making good art.
     
  46. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    8,396
    You can nuke most of the comments there, because variable names are self-descriptive.
    I think the only useful thing there was "This stuff is for google", but rather than being a comment it should've been turned into a [Header("Google promo stuff")] which would also organize things in inspector.
    You'll further improve code quality if you'll start using different case for variables and types - in this case you'll be able to discern which is which at a glance. In my code type names always start with uppercase letter, while methods and variables start with lowercase. You could do that or use comparable approach.

    In general, I think that the code should be as self-descriptive as possible. However, things like 0x5f3759df either require an explanation, which could be provided as a comment. On other hand, this case could be treated as a magic number, and ideally 0x5f3759df should've been declared as a named constant, which would eliminate need for a comment.
     
    DroidifyDevs likes this.
  47. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,412
    Then there's the Dunning Kruger effect which leads some to believe they write great code when they just can't see how bad it is vs those who believe their code is poor because they can identify the their flaws and know it can be better.

    I prefer working with the latter developer and their code :)

    Note, going by this I must be an awesome programmer as I'm sure my code sucks!
     
    frosted likes this.
  48. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,244
  49. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,412
    Absolutely - I was going for a quick way for *me* to verify his code - 1) I didn't want to have to walk through how to use a debugger (if that OP was familiar with debugging I'd assume they'd have already stepped through it). 2) That trace print I asked for will give *me* what I'd need to see how it steps through.
     
    sylon likes this.
  50. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,244
    Are you being serious?
    Code (CSharp):
    1. print("Resetting Queue");
    2.             print("** 1 **");
    3.             autoFillQueue.Clear(); //I only reset the queue when a letter is changed and the queue is not empty. This is not the problem.
    4.             print("** 2 **");
    5.             keyPressed = false;
    6.             print("** 3 **");
    7.             autoFillIndex = 0; //Just a variable to keep track of the index. Works fine.
    8.             print("** 4 **");
    This would have been enough:
    Code (CSharp):
    1. print("Resetting Queue");
    2.             autoFillQueue.Clear(); //I only reset the queue when a letter is changed and the queue is not empty. This is not the problem.
    3.             keyPressed = false;
    4.             autoFillIndex = 0; //Just a variable to keep track of the index. Works fine.
    5.             print("** 1 **");
    There were no errors, jumps or conditional statements, so you can safely assume that block executed fully.
    But hey, whather helps you code at night. :)
     
unityunity