Search Unity

Question Vote for coding standards

Discussion in 'Open Projects' started by Kamyker, Oct 1, 2020.

?

Pick max 2 preferred coding standards/naming conventions

  1. C# (uppercase public fields)

  2. C++ (lowercase public fields)

  3. NO prefix for private fields (playerHealth)

  4. "_" prefix for private fields (_playerHealth)

  5. "m_" prefix for private fields (m_playerHealth) (used in fps microgame)

  6. Whatever (aka complete mess)

Multiple votes are allowed.
Results are only viewable after voting.
  1. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    On Github you do ?ts=X to set custom width, for ex. https://github.com/Facepunch/Facepu...aster/Generator/Types/FetchStringType.cs?ts=2

    Doesn't work with spaces: https://github.com/DapperDino/UOP1/...ssets/Scripts/Characters/Protagonist.cs?ts=10
    I recommend the same :). 2 main reasons to use them is:
    1. Code completion

    2. Better readability on github

    On side note, I voted for no prefixes but I'd swap my vote after discussion in this thread.
     
  2. Languard

    Languard

    Joined:
    Nov 2, 2009
    Posts:
    8
    The var type is horrible and should not be used in a learning project. It introduces hard to track errors when return types change or if something is used incorrectly and offers no benefits over strict data types in most cases. There are some extreme cases where it might be useful, but there is no reason to use var.

    Edit: Many JavaScript experts don't like var. That should say something.
     
    SideSwipe9th likes this.
  3. MagdielM

    MagdielM

    Joined:
    May 27, 2020
    Posts:
    32
    I've said earlier in the thread that we should just follow the official C# conventions, but let me elaborate on why: for someone learning the language, it becomes easier to follow along when learning from resources outside our little open project. There is probably more code "out in the wild" following the Microsoft spec than not, be it from tutorial articles, StackOverflow answers, or Youtube videos, so newcomers (especially those new to programming in general) will find learning from this project easier if it follows the same structure as other material they may have encountered.

    As a personal anecdote, I distinctly remember stumbling a few times when I was trying to get into Android development because the Oracle tutorials led me to believe you couldn't prefix any variable at all, so seeing all the
    m
    prefixes on private static fields made me think the names had some sort of special meaning.
     
  4. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
  5. melkior

    melkior

    Joined:
    Jul 20, 2013
    Posts:
    199
    I really hope we don't go with the var for everything.

    In my experience when I mentor and teach and go to game jams programmers who are new to the language find the use of var confusing. Implicit types take a little bit more time to analyze before you start really getting it. Once you are really well versed with all the types of a language then implicit types get easier to understand (IMO).

    If the goal is to invite more contributions - or at least have the output of this project be something new programmers could download and see examples of that make sense to them I think explicit typing most of the time makes more sense for an open collab like this.

    That's my 2 cents anyways.

    Also my preference would be:
    - no prefixing
    - lowercase variable names
     
    SideSwipe9th likes this.
  6. Little-Big-Monkey

    Little-Big-Monkey

    Joined:
    Mar 4, 2014
    Posts:
    40
  7. Deleted User

    Deleted User

    Guest

    This is CSharp in Unity, follow the Unity conventions. :p
     
    Last edited by a moderator: Oct 5, 2020
  8. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    Now we stuck in eternal loop :(
     
    Deleted User likes this.
  9. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    JavaScript var and C# var (and for that matter, C++ auto) are not the same. JavaScript var is more akin to C# dynamic, where it is a dynamically typed object with no intellisense or compile-time checking. C# var is implicit typing (as is C++ auto), it is still strongly typed. It is syntactic sugar to reduce typing while still providing strong typing and code correctness. I feel like this statement in particular demonstrates to me that most people who are arguing against var are ignorant to what it actually is. There is no functional difference between these two declarations:

    Code (CSharp):
    1. List<int> myVerboseList = new List<int>();
    2.  
    3. var myVarList = new List<int>();
    They are both treated as List<int> by the compiler and the IDE.

    EDIT: Does anyone have an actual, non-contrived example of how they feel that using "var" could actually cause an issue?
     
    Last edited: Oct 5, 2020
    Basa0 and MUGIK like this.
  10. SideSwipe9th

    SideSwipe9th

    Joined:
    Jan 10, 2019
    Posts:
    46
    Both myself and @melkior have posted in this thread our own experience with var typing. Before I got into gamedev I was involved with teaching at university. The one thing we never, ever did was to teach implicit typing to beginner programmers. We found through repeated experience that it confused many, and resulted in reduced student attainment. Typically we would not introduce implicit typing until at least year two of a degree to ensure those students had the fundamentals down.

    As I said in my previous reply in this thread, part of the goal for this initiative is teaching. Using var will make it much less accessible for newer programmers. @melkior above has posted his experience with mentoring, teaching, and game jams and it reads similar to my own.

    That C#'s var type is actually dynamically strongly typed behind the scenes is irrelevant, because that's not the issue at hand. The problem with var is code readability.

    Code (CSharp):
    1. public List<string> exampleFunction(){
    2.     List<string> result = new List<string>();
    3.     ...
    4.     return result;
    5. }
    6.  
    7. void Update(){
    8.  
    9.     List<string> explicitListOfString = exampleFunction();
    10.     var implicitListOfString = exampleFunction();
    11.    
    12. }
    In this example, without looking at exampleFunction, can you tell me what type implicitListOfString is? What if I hadn't called it implicitListOfString but instead called it functionResult? Now you can argue here that we're getting into a separate argument over meaningful variable names, and don't get me wrong there is merit in having your variables well named. However even a well named variable will still require you to check what exampleFunction is returning if your code is broken.
     
  11. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    While this is an exercise to be open for relative beginners, I don't think this is going to be for "people who have never touched C# in their lives." In order to contribute, you have to work with git - not exactly something a CS101 student is going to be tackling. I had a coworker who was similarly uncomfortable with var, and they would use similar tactics to attempt to codify their discomfort into our coding standards . But we used var, the code is highly readable, we push tens of million dollars of revenue through a system far more complex than what we are going to be doing here, we do code reviews and have not had an issue with its usage, and their discomfort went away over time when they realized that C#'s syntactic sugar was there to make the code more readable, not less. I asked for an uncontrived example, and this isn't one. As I said in an earlier post, even if you use explicitly typed variables, that is no excuse for poor variable and function naming. I'd be interested in seeing a real example of a variable and function with meaningful names for which the usage of var somehow robs it of its readability.

    And specifically, we are talking about "readability in a git pull request" as well. Because "my code won't compile because I changed something without understanding what it was I was changing, read the compiler errors" is a valuable enough lesson for any reasonable novice developer to learn that I don't mind them learning this way. A pull request requires a passing build to be considered, so that isn't a concern.

    Also, while I have never taught programming in an academic setting (though I have mentored many people), I have a bit of trouble believing that implicit typing is somehow the massive barrier of entry that it is being portrayed as here, when Python uses dynamic typing (orders of magnitude higher chance of shooting oneself in the foot) and it is many students' introduction to programming.

    EDIT: Also there's this notion that you're going to be able to do a code review or programming without checking what is happening in the methods that are being called, as long as you have explicitly typed variables. That is utterly absurd, and misdirection at best. Knowing that a method returned a List of strings tells you absolutely nothing about what it's actually doing. If you have these two lines of code:

    Code (CSharp):
    1. List<string> explicitList = exampleFunction();
    2.  
    3. var implicitList = exampleFunction();
    You still need to know what "exampleFunction" is doing, whether you know what type it's returning or not.
     
    Last edited: Oct 6, 2020
    jsjdev91 likes this.
  12. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Random code:
    Code (CSharp):
    1. for ( int j = 0; j < sheet[0].Length; j++ )
    2. {
    3.     if ( j >= sheet[i].Length )
    4.         break;
    5.     var curObject = parentObject;
    6.     var cell = sheet[i][j];
    7.     var columnName = sheet[0][j];
    8.     if ( !string.IsNullOrEmpty( cell ) && !string.IsNullOrEmpty( columnName ) )
    9.     {
    10.         FieldInfo fieldInfo = null;
    11.         if ( columnName.Contains( "." ) )
    12.         {
    13.             var variablesSplit = columnName.Split('.');
    14.             var prevObjectField = curObject;
    Code (CSharp):
    1. for ( int j = 0; j < sheet[0].Length; j++ )
    2. {
    3.     if ( j >= sheet[i].Length )
    4.         break;
    5.     object curObject = parentObject;
    6.     string cell = sheet[i][j];
    7.     string columnName = sheet[0][j];
    8.     if ( !string.IsNullOrEmpty( cell ) && !string.IsNullOrEmpty( columnName ) )
    9.     {
    10.         FieldInfo fieldInfo = null;
    11.         if ( columnName.Contains( "." ) )
    12.         {
    13.             var variablesSplit = columnName.Split('.');
    14.             object prevObjectField = curObject;
    This isn't a big problem:
    Code (CSharp):
    1. List<string> explicitList = exampleFunction();
    2. var implicitList = exampleFunction();
    This is a problem:
    Code (CSharp):
    1. List<string> explicit = exampleFunction();
    2. var implicit = exampleFunction();
    Poor naming + var is even worse. It's actually a very good excuse when scope of variable is small and type is more important than variable name.
     
    kcastagnini likes this.
  13. SideSwipe9th

    SideSwipe9th

    Joined:
    Jan 10, 2019
    Posts:
    46
    Okay, if my experience as a teacher doesn't convince you let me turn the question back at you. Do you or anyone else have an actual, non-contrived example of how you feel that using explicit typing could actually cause an issue? What benefits does var bring beyond saving keystrokes? Which is kind of a non-issue anyway in a world of autocompleting IDEs.
     
    kcastagnini likes this.
  14. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    With the two "random code" examples, var doesn't impact the readability to me. The random "object" that was clearly inserted into this CSV/spreadsheet processor in order to make it seem like having explicit types adds value is probably the most egregious, and since you basically can't do anything with all object other than casting or calling ToString, that doesn't cause me any concern. Especially because you're attempting to make the code look more complex by removing the context of behavior (which is what I'd actually be looking for.) With the behavior in place, such as on line 13 where you are calling Split, you use var in both and it doesn't remove the ability to understand what's happening.

    I mean, agree to disagree then. I'll reject a PR with an unclear variable, and the type of an object is rarely (never?) more meaningful than what you're doing with it.
     
  15. Zold2012

    Zold2012

    Joined:
    Feb 4, 2014
    Posts:
    67
    upload_2020-10-5_21-43-14.png

    i didn't learn about 'var' until a few years after starting working in unity so i've never really used them
     
    kcastagnini and SideSwipe9th like this.
  16. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    I don't think I've implied that explicit typing causes any issues. I wouldn't block a PR for having only explicit types unless it hinders readability (in the uncommon situation with excessive generics on a line for declaration):

    Code (CSharp):
    1. Dictionary<Type, IList<(string, int, int, float)>> collection = new Dictionary<Type, IList<(string, int, int, float)>>();
    2.  
    3. var collection = new Dictionary<Type, IList<(string, int, int, float)>>();
    I'll argue to my dying day that the latter is more readable.

    But I'm not arguing that we should only use var I'm arguing against banning the use of var for basically reasons that people are uncomfortable with syntactic sugar.
     
    Zold2012 likes this.
  17. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Yes, I do the same when it's trivial to understand the type. That's why I did
    var variablesSplit = columnName.Split('.');


    Btw that
    (string, int, int, float) 
    looks scary, don't tell me that u use tuples everywhere instead of structs.
     
    tmcdonald likes this.
  18. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    Yeah tuples are crazy looking even with the new syntactic sugar and I definitely prefer putting them into a real class or struct. Like if someone said "let's avoid tuples" I'd agree. I just needed something I could type out on a phone that had some length.
     
    Neonage likes this.
  19. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    Panic in the palace!
    R e a d a b i l i t y and consistancy.
    Which code is more succinct? Yes, first one.
    Variable and function naming tells everything you need.
    Edit: Kamyker code is actually example where not to use var, indexing like this needs to be explicit.

    When I see explicit type is used instead of var, I'm thinking that it's doing something special, like implicit convertion.
    For ex: float3 velocity = Vector3.ClampMagnitude(...)

    So I would prefer to stick with var where it is trivial to understand the type
     
    Last edited: Oct 6, 2020
  20. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Var is worse, when I look at
    var cell = sheet[i][j];
    I have no idea what it is, I have to read other lines to understand it. This sometimes ruins reading code (or snippets of code on github) from top to bottom and in the end makes it more complicated.

    I'm saying this from my experience of reading someone else code or going back to my own 1y+ old code. I was using var a lot as beginner but stopped when I realized it's worse.
     
    Last edited: Oct 6, 2020
    kcastagnini likes this.
  21. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    Yes, I've already edited my post on this.
    That why I actually hate using multi-dimensional arrays.
    What I would use is flat array and nicely named function for indexing
     
  22. MileyUnity

    MileyUnity

    Joined:
    Jan 3, 2020
    Posts:
    92
    Quick note to everyone in this thread, we're still working on the coding style for this project, it will be based of off the .net coding style with some of our own flavors. Once we have it we'll post it here
     
  23. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Hopefully not
    m_
     
    cirocontinisio likes this.
  24. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    You don't like the flavour of
    m_
    ? :D
     
    kcastagnini and tmcdonald like this.
  25. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    I have allowed myself to paste some conventions from this link:
    I would add:
    UPPER_CASE with _ as separtator of words for constants.

    PascalCase for enum members.

    Don't use var if you don't have to. (allowed in foreach(var item in collection) but don't do it when item type name is short)

    Use ...Component in name for classes inherited from MonoBehaviour.

    When doing abstract class derived from MonoBehaviour prefix with "I". ex: "abstract class IStrategyComponent:MonoBehaviour"

    Keep the base type name when inheriting ex: WinningStrategyComponent:IStrategyComponent






    Lately I was thinking if I should not use underscore in some classes name ex: Winning_StrategyComponent:IStrategyComponent

    This makes clear distinction between name and type.
    Right now it happens that I have ...StrategyComponentStrategyComponent kind of names.


    What about brackets ...
     
  26. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    I forget one thing.
    Don't use public fields that are not going to be serialized.
     
  27. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Stoooop, I can't look at it, gonna have nightmares of Unsolvable M_atrix (hmm that could be a good movie)

    Weird one, I is interface.
     
  28. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    If MonoBehaviour was an interface "IMonoBehaviour" than we would not have a problem. But it is not so when we want to have kind of similar "entity" we have to simulate it. That's why I mark it with "I". Naturally you might use different prefix for example "Base" but I want to make this distinction, when I use "Base", class is not abstract.

    public class BaseFooComponet:MonoBehaviour
    public abstract class IFooComponet:MonoBehaviour
     
  29. MagdielM

    MagdielM

    Joined:
    May 27, 2020
    Posts:
    32
    Nah, Wendy's all the way. You eat your M_cGarbage if you want.
     
  30. kcastagnini

    kcastagnini

    Joined:
    Dec 14, 2019
    Posts:
    61
    lol i use that srry rofl
     
  31. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    Hey all, we've put together some conventions based on your input + some common sense practices.
    We tried not to make them too long (or else the majority of the users won't read them):

    Open Projects: Code and Project Conventions

    Please keep putting in this very thread all the feedback on the above, keeping in mind that we want to keep it relatively entry-level and short.

    Also, you probably noticed that @MileyUnity implemented a "linter" on the repo, so every commit is going to be automatically analysed and corrected by a bot. If you find issues with that, let us know here in the thread or open an Issue directly on Github.
     
    Basa0, kcastagnini, tmcdonald and 2 others like this.
  32. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    May I ask why scenes go to the root folder ?
    I think this is a bad idea,
    I think scenes should go into it's own directory and also every scene should have it's separate directory.
    ex: Scenes->DarkForestScene->DarkForest.unity

    This because there might be data associated with the particular scene.
    Deleting scene directory should delete all associated data.

    There might be single scene in the root folder. Lets call it "RootScene".
    So it is easy to open the project. This scene could have some helping info.
     
    SideSwipe9th and MUGIK like this.
  33. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    upload_2020-10-7_22-49-23.png

    upload_2020-10-7_22-48-47.png

    upload_2020-10-7_22-42-1.png


    I don't feel so good..
     
    adamgolden likes this.
  34. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Meh, there are better ways than Singletons and SO but for source control SO may be even worse than Singletons. https://forum.unity.com/threads/scriptable-objects-workflow.982185/#post-6381090
    You'll see soon when project gets bigger.
     
  35. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
  36. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    In what scenario?
    In a game like this where scenes will mostly be locations, but they will share a lot of assets among them, deleting the scene shouldn't delete the directory.

    For instance, there might be 10 forest Scenes and they all use a certain tree Prefab, but maybe that tree Prefab is also used in a town Scene. Where do you put it? (or where do you put these Scene files?)

    I see your point on the events. But there's no one pattern that will cover all use cases and also provide all the advantages while none of the disadvantages, so we will see!
     
    Neonage likes this.
  37. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    I might have been not precise enough.
    By scene data I don't mean shared data, but more of a unique scene data. Sometimes you need to generate per scene data like for example pathfinding data or profiles data.
     
    SideSwipe9th likes this.
  38. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    Why put scene inside scene data folder? It's just makes it harder to find.
    And in this case newly created data would create another sub-folder with the same name.
    upload_2020-10-7_23-41-34.png
     
  39. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    Encapsulation, as I said before when you have directory for a scene you can put there unique scene related data and don't have a mess in your project. This is also why "Scenes" directory is mandatory. To keep scenes in one place and not to creep the root directory.
     
  40. MUGIK

    MUGIK

    Joined:
    Jul 2, 2015
    Posts:
    481
    Let's also add '_' in this example to make it clear:
    upload_2020-10-7_20-2-58.png


    What about just using 'default' everywhere?
    Code (CSharp):
    1. [SerializeField] private Vector3 someVector = default;
    upload_2020-10-7_20-4-45.png


    What about private serialized fields?
    upload_2020-10-7_20-12-49.png
     
    Last edited: Oct 7, 2020
    tmcdonald likes this.
  41. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    Fine with me. I'm on a phone right now so I might have missed it, but did y'all cover explicit use of private? e.g. do you want us to explicitly declare everything as private, or just leave it off by default?
     
  42. Neonage

    Neonage

    Joined:
    May 22, 2020
    Posts:
    287
    I still vote to not use '_' prefix at all.
    It's not only makes code harder to read, but newcomers may think that this is something special for code compilation, like if they don't do this, the code will work differently (like people do in Python).

    var is mandatory where type is trivial / double typed.
    Code (CSharp):
    1. var componentsPerInstance = new Dictionary<GameObject, Component>();
    2. var color = new Color();

    And constants.. Why don't we use sub-classes for them?
    For ex.
    Consts.GravityAmount
    instead of
    GRAVITY_AMOUNT
     
  43. SideSwipe9th

    SideSwipe9th

    Joined:
    Jan 10, 2019
    Posts:
    46
    I tend to agree with the above with respect to scene placement. In the studio I work at, we keep separate our scenes, art assets, systems code, and audio assets with one folder for each (eg 1. Art Assets, 2. Systems, 3. Scenes). We use the number dot naming scheme for this to ensure that content we have created appears first in the project view hierarchy before anything we may have imported from the asset store or elsewhere.

    Our scenes folder only contains the scenes, and any per-scene generated artefacts like nav meshes and lightmaps. Dumping all of those into the root Assets directory of the project can make it hard to find a specific scene, even with the filtering/search options.


    Prefabs are stored in a separate folder to your scene, with its own structure and naming conventions. In my studio we currently store the object prefabs inside the art assets folder, though we may change that as we're looking at re-organising and sorting through our projects in the near future.
     
    Last edited: Oct 7, 2020
    koirat and tmcdonald like this.
  44. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    We are talking about constants using "const" keyword not some kind of game constants.
    We want to distinguish them from other type of constants.
    Constant might be a part of a class, even private so no need to create some other class.
    Consts.GravityAmount - this looks like an enum.
     
  45. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    Can you give an example. I'm using "_" prefix in my project if I want something to appear at the top and retain alphabetical order.
    ex: "_Scenes" ( actually I'm not using it for scenes ;) )
     
    MUGIK likes this.
  46. Little-Big-Monkey

    Little-Big-Monkey

    Joined:
    Mar 4, 2014
    Posts:
    40
    This is so hard to read, when usual rule is :

     
    Laicasaane and Neonage like this.
  47. cirocontinisio

    cirocontinisio

    Joined:
    Jun 20, 2016
    Posts:
    884
    Good suggestions, I added them in.

    Unity actually gets rid of the _ in the Inspector:

    upload_2020-10-8_0-10-45.png

    They're never mandatory :)

    Because then they are not constants. They are just variables, living somewhere else!

    PS: I don't usually use underscores for private fields myself. In fact I voted "NO prefix for private fields" in the survey. But that's not the solution that was voted the most... so we chose the one which was.
     
    SideSwipe9th likes this.
  48. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    Sadly right now it is 103/101 for prefixes.
     
  49. SideSwipe9th

    SideSwipe9th

    Joined:
    Jan 10, 2019
    Posts:
    46
    Same basic idea as using "_" as a folder name prefix, the only difference being you get to chose what goes to the top of the project view instead of it being alphabetically sorted. Our "1." folder is typically "1. Art Assets".
     
    koirat and tmcdonald like this.
  50. tmcdonald

    tmcdonald

    Joined:
    Mar 20, 2016
    Posts:
    160
    I'm a fan of this folder naming convention.