C# GAME ENGINE BY 16-YEAR-OLD! // Code Review

Поділитися
Вставка
  • Опубліковано 27 сер 2024

КОМЕНТАРІ • 582

  • @TheCherno
    @TheCherno  2 роки тому +113

    Thanks for watching! More C# code reviews? Also don't forget to visit brilliant.org/TheCherno/ to get started learning STEM for free, and the first 200 people will get 20% off their annual premium subscription! ❤️

    • @Dustyy01
      @Dustyy01 2 роки тому +4

      First time i didn't skip the sponsored ad, so well presented 😂

    • @Stabby666
      @Stabby666 2 роки тому +1

      Heh, this reminds me of years back when I was converting old arcade games over to run in JS for fun, and then they started popping up on other sites, just with my name removed from the code etc. I then started adding weird variable names so I could google for them, and contacted the people who were pretending they'd written the games themselves. In almost EVERY case they apologised with "Oh, I didn't think you'd mind". I wouldn't have minded - I never made money from them in any way, but having other people claim they wrote the code you worked hard on is a bit disrespectful...

    • @wcdeich4
      @wcdeich4 2 роки тому

      Are there any good JavaScript 3D frameworks besides Three.JS?

    • @Stabby666
      @Stabby666 2 роки тому +1

      @@wcdeich4 ThreeJS is great. I've used it for a lot of event installation work and its been really reliable. There are other game engines for JS though if that's what you need.

    • @potterloko0175
      @potterloko0175 2 роки тому +5

      Yes. more C# code!!!

  • @TechRevi
    @TechRevi 2 роки тому +353

    One question mark broke Cherno for like 10 minutes.

    • @lightknight876
      @lightknight876 2 роки тому +36

      In fairness to this genius, he did warn us about his c# skills

    • @tavaroevanis8744
      @tavaroevanis8744 2 роки тому +7

      The difference in time between Cherno's puzzled state versus mine would be 10 hours, not 10 minutes.

    • @AntoninHoudekidk
      @AntoninHoudekidk 9 місяців тому +4

      btw, it only works if u enable it in csproj by `enable `, so by default its not how it actually works

    • @perrylets
      @perrylets Місяць тому

      Except that all templates have it on by default​, so you need to createthe cspeoj by hand or change it on purpose for it to not be enabled @@AntoninHoudekidk

  • @asmrtv2566
    @asmrtv2566 2 роки тому +193

    Every time a video like this is uploaded I feel dangerously stupid.

    • @tiesjongebreur2770
      @tiesjongebreur2770 2 роки тому +2

      🤣

    • @lanchanoinguyen2914
      @lanchanoinguyen2914 Рік тому +4

      C# is for noobs

    • @rmt3589
      @rmt3589 11 місяців тому +3

      ​@Morrisson._Python, C++, or Assembly, in that order?

    • @ThisShitWontWor
      @ThisShitWontWor 9 місяців тому +20

      Real g use assembly in a hex editor

    • @mateuszgaecki5949
      @mateuszgaecki5949 9 місяців тому +11

      ​@@lanchanoinguyen2914exactly. I use only machine code. I don't udnerstund why would anyone use a "programming language". More like "I'm an idiot language"

  • @LRAnimations
    @LRAnimations 2 роки тому +550

    Those new non-nullable features are actually a big thing and most modern programming languages are moving towards approaches like this. For example Kotlin, Dart, Typescript. They all work like this, where everything is considered non-nullable until you specifically say its nullable. This is really helpful, because most of the cases you don't need things to be nullable and in the cases you do need them to be nullable, the compiler helps you checking if its null or not before doing operations on it. Also when you do stuff like if (variable != null) {, inside the block after the if, the variable gets promoted and the compiler automatically considers it to be non-nullable, which is just amazing

    • @flerfbuster7993
      @flerfbuster7993 2 роки тому +74

      I like Rust's approach the most. The concept of null doesn't exist in that language, so if you need to represent "nothing", you need to wrap your value with an Option type. This way, you always have to explicitly handle the possibility of no value, essentially preventing null references.

    • @andy010
      @andy010 2 роки тому +16

      most people don't know this, but you can actually chage that behaviour, by modifying the .csproj file. It also allows to get the old using behaviour back

    • @nxte8506
      @nxte8506 2 роки тому +12

      Yes it is really helpful, I’m a typescript dev and it’s one of the things that makes web development so much easier. Now most of the runtime errors I face are just browser incompatibility issues like an api not being available on the window in some browsers. Typescript usually helps as much as possible in these cases.

    • @luk17032000
      @luk17032000 2 роки тому +8

      @@flerfbuster7993 what also great about is, that this is a zero-cost abstraction as rust represents the None as a null pointer, while the Some just points to the memory location.

    • @ko-Daegu
      @ko-Daegu 2 роки тому +12

      Python & JS dev: what are y’all on about 🙃

  • @tanmaypanadi1414
    @tanmaypanadi1414 2 роки тому +53

    45:00 the moment cherno realised it's his code.
    Thanks Sam 🤣 for the code.
    *insert Spiderman meme*

  • @frederikja2210
    @frederikja2210 2 роки тому +321

    Im one of the maintainers of OpenTK, and it is really interesting to watch through someone critiquing a project made using a library i have helped so much.
    I have spent way more time developing opentk itself than making products with it. So very interesting watch.

    • @smrtfasizmu6161
      @smrtfasizmu6161 2 роки тому +3

      I'm just curious, what language do you use to make these libraries and how are libraries which allow dealing with graphics even made, like how is opengl, glfw, freeglut, or awt and swing libraries for Java even made?

    • @jashitshah3897
      @jashitshah3897 2 роки тому +9

      @@smrtfasizmu6161 to the best of my knowledge, it just starts off with a couple of system-provided methods that allow you to open a window and draw a bunch of pixels, and it builds up from there using a whole lot of math. For starters you could take a look at projection matrices to get a feel of how 3D stuff is rendered on a 2D screen.

    • @smrtfasizmu6161
      @smrtfasizmu6161 2 роки тому +1

      @@jashitshah3897 but how do you accès these system methods, can I access them from within my program? If not, then how do these libraries access it? Do they get some special permission from Microsoft? I mean, I don't know how to do that in Ubuntu either.

    • @sps014
      @sps014 2 роки тому +6

      Thanks for your amazing work

    • @jashitshah3897
      @jashitshah3897 2 роки тому +5

      @@smrtfasizmu6161 it usually differs from one operating system to another. For example, the Windows API abstracts this functionality for you in Windows. So when you create a traditional desktop app in C++, it starts off with this WinAPI. For other languages, the functionality is just C or C++ wrappers. I don't exactly know the Linux equivalent to WinAPI, but it works on pretty similar basis.

  • @r1pfake521
    @r1pfake521 2 роки тому +115

    Since you asked about C#, I would be interested to see you talk about your C# scripting integration in Hazel

    • @Knollee_oder_so
      @Knollee_oder_so 2 роки тому

      ⇑ This please

    • @bendywills859
      @bendywills859 2 роки тому +1

      Yes, please.

    • @iXmerof
      @iXmerof 2 роки тому

      Yes, definitely, please tell us how you script other language's code

  • @ironnoriboi
    @ironnoriboi 2 роки тому +185

    C#'s new nullable (which needs to be explicitly enabled) is really nice. Especially for large codebases, you no longer need to check for null in every method that receives a class as argument unless its an Optional (? postfix) type.

    • @Mischu708
      @Mischu708 2 роки тому +2

      It's also good for asp backends since you use optionals everywhere when you talk to the database(your fields may or may not be null).

    • @HermanWillems
      @HermanWillems 2 роки тому

      A language should not contain null. Also default variables should be not muttable. Also C# error handling blegh. Languages without NULL always work way better.

    • @ironnoriboi
      @ironnoriboi 2 роки тому +15

      @@HermanWillems Every way of working has its usecase, including null values.

    • @vishaalshiva2009
      @vishaalshiva2009 2 роки тому +2

      Is C# nullable any different from Swift's optional? To me, they appear to perform the same function.

    • @HermanWillems
      @HermanWillems 2 роки тому

      @@ironnoriboi then why the inventor of NULL regrets it and wishes he never invented it?

  • @QckSGaming
    @QckSGaming 2 роки тому +89

    Rendering architecture was probably the biggest hurdle after figuring out OpenGL so would definitely be a helpful video for a lot of people!

    • @garlfin
      @garlfin 2 роки тому +10

      all the opengl tutorials teach you how opengl works but not the architecture of something that could be commercial so I kinda just went with whatever I thought of. garengine was my first "engine" and gESilk I improved on what I thought could be different.

    • @QckSGaming
      @QckSGaming 2 роки тому +4

      @@garlfin It's extremely good. You are gonna make a great graphics programmer in the future and get paid well :P Already ahead of engineering bachelors

    • @garlfin
      @garlfin 2 роки тому +6

      @@QckSGaming that’s really nice to hear :)

    • @theinventor8793
      @theinventor8793 2 роки тому

      @@garlfin Why not use C++?

    • @garlfin
      @garlfin 2 роки тому +1

      @@theinventor8793 dunno I just don’t like c++

  • @voxelrifts
    @voxelrifts 2 роки тому +37

    I was a part of the discussion where Sam helped garlfin with the bloom and he did make it clear that this was your code but slightly modified for better names for garlfin to understand.
    He didn't mean to steal your code just saying :D

    • @asherhaun
      @asherhaun 2 роки тому +4

      LOL, I had a suspicion that the sam was from the GWG discord, but I just found the conversation. I knew I had seen that model and scene somewhere before.

    • @ltl-cx9xs
      @ltl-cx9xs 2 роки тому

      Glad to see the problem resolved. But still, this is great work by someone who is 16.

  • @scottwalker4619
    @scottwalker4619 2 роки тому +65

    I wasn’t sure about the nullability improvement in C#8 but after using it for a few years I’ve became a fan. It forces you to think a lot more about the code you’re writing and you can change the compiler settings to force a compile failure when there is a potential null reference exception. It came after some statistics were released that said something like 80% of all exceptions in C# are null reference exceptions.
    But if you don’t like it, you can always turn it off and choose not to use it.

  • @asherhaun
    @asherhaun 2 роки тому +50

    I really enjoyed seeing a dive into a C# renderer and the critiques of the architecture.
    It would be great if you made a video about basic openGL rendering architecture like you mentioned.

    • @megaflup
      @megaflup 2 роки тому +1

      this

    • @jondoe6608
      @jondoe6608 2 роки тому +1

      yep, id love that opengl video to be made!

    • @pieTone
      @pieTone 2 роки тому +2

      Yoo asher be here also

    • @asherhaun
      @asherhaun 2 роки тому

      @@pieTone naturally :D

  • @ianknowles
    @ianknowles 2 роки тому +95

    The null-able opt-in is a tad useless in your case but if you declare something as not null then it forces you to set in the constructor. Which is really handy in c# especially when dealing with DI..

    • @monad_tcp
      @monad_tcp 2 роки тому +4

      Its not useless if you flip that switch on the compiler to require assertions.

    • @ianknowles
      @ianknowles 2 роки тому

      @@monad_tcp point in kind its there for a reason... We usually have CI/CD pipes pick up these kinda errors.

    • @monad_tcp
      @monad_tcp 2 роки тому +1

      @@ianknowles no, CI/CD is not to pick those errors. They are for integration and functional tests. Those tests that test for conformance to the specs.
      The entire purpose of a statically typed system is to catch those kind of errors (nullability) as you type the code, besides for CI/CD to work, you need to write the tests. You want to test real functionality, not correct input to functions, this is just part of the contract of the function, you test the implementation. (that was used to be called unit testing from electrical engineering, before it was subverted to do what type systems do, because of languages like Python/Ruby/Javascript)
      I'm totally against unit testing. Type systems were designed to catch boundary errors automatically.
      Csharp is a tad outdated in this regard, which is why I'm switching to F#, because of a better type system.

    • @monad_tcp
      @monad_tcp 2 роки тому

      That said, the new non-null by default goes a great way to reduce errors.
      That's the problem with testing in general, you make an error and try to find it and fix.
      This is stupid, I'm much prefer tools that make entire classes of errors impossible.
      Which is why I'm totally against unit testing on statically typed languages.

    • @monad_tcp
      @monad_tcp 2 роки тому +1

      Come on, that's basic software engineering, the earliest you catch the error, the cheapest is to fix it.
      What's earlier than not even being able to write the error? Because the compiler will flag it as you type...
      (earlier than that only your brain...)

  • @TizzyT455
    @TizzyT455 2 роки тому +22

    Being mainly a C# programmer myself I'd love to see more C# videos but I would like to see a bunch of other languages too. Also I think the diagram thing you were thinking of was a dependency graph? Its a feature only available I think in the professional or enterprise versions.

  • @nitrous1001
    @nitrous1001 2 роки тому +18

    I started watching your channel in learning computer graphics and a bit of interest of C++ programming but I'm mainly geared towards C#. Because of it, I'd love to see more C# code reviews as well!

  • @chadwad12
    @chadwad12 2 роки тому +6

    As mentioned in previous comments, in this case in the code the nullable reference type didn't really mean much and really didn't need to be there. But the feature is a great feature to have turned on in projects. There is actually stories of major libraries turning it on and actually finding bugs that they never knew were there because the compiler could actually tell you that "hey this could be null." Most modern languages are implementing things like this. NULL is something most languages are really trying to force out of the language now. I recently just wrote a library for something at work with the feature turned on and it really helped me out a lot.
    I am learning Swift and it's similar, and I love it. I've yet to actually run into a null pointer exception because the compiler will really force you to think about "are you sure you want to do this...I could be null."

  • @rafaeldeconde8148
    @rafaeldeconde8148 2 роки тому +16

    I particularly prefer the C++ reviews, but once in a while is good to have other languages. Awesome review!

  • @bity-bite
    @bity-bite 2 роки тому +8

    @ 7:33 The NRT feature was introduced in C# 8 to *basically* protect developers from making null reference exceptions.

  • @ruannilton5119
    @ruannilton5119 2 роки тому +18

    I see a big problem with this ECS implementation, since Component is a class, we can not controll where his objects will be instantiated, even when we have a List behind the hood what we have is just a list of references, the true objects will be spread in the application memory.

  • @jpack61108
    @jpack61108 2 роки тому +1

    This is probably the most informative code channel ive come across on youtube. i appreciate that.

    • @infinityminuszero
      @infinityminuszero 2 роки тому

      I suggest you also check Nick Chapsas if you're looking for a good C# channel

  • @lukefidalgo8154
    @lukefidalgo8154 2 роки тому +27

    16:52 I'm pretty sure you _can_ start your variables with _ in C++, or at least MSVC supports it

    • @kapilverma2668
      @kapilverma2668 2 роки тому +6

      GCC also supports naming variables with Underscore< _ >. C++ identifier rule states that name can start upper or lower case alphabet or Underscore but not a number.

    • @ohwow2074
      @ohwow2074 2 роки тому +8

      _ is reserved for future uses in standard library. You shouldn't use them in your code.

    • @ChlorieHCl
      @ChlorieHCl 2 роки тому +6

      You can name your identifiers _like_this but not _Like_this. Also if the identifier in question is global then starting with underscores would not be allowed. So most people just don't bother risking that and just use other naming schemes.

    • @dmail00
      @dmail00 2 роки тому +1

      You can as long as it is not in the global scope and is not followed by another underscore or a capital letter.

    • @dmail00
      @dmail00 2 роки тому

      Just for anybody interested why it is used in C#: C# Coding standard from msdn "Use camel casing ("camelCasing") when naming private or internal fields, and prefix them with _." ... "When editing C# code that follows these naming conventions in an IDE that supports statement completion, typing will show all of the object-scoped members."

  • @Chiramisudo
    @Chiramisudo 2 роки тому +27

    14:21 I was also 16 when I started programming, but didn't get to run my first line of code until I was 17 because I was too poor to afford a PC back in the 90s when they were several thousand $, so I "programmed" with paper and pencil. On the plus (or rather C++) side, all my code was bug free. 😋

  • @smrtfasizmu6161
    @smrtfasizmu6161 2 роки тому +14

    I was told the same thing about static variables from experienced programmers on the Internet that Cherno said about 20:00. And Cherno also nailed the reason why I used static too much in my biggest Java project that I have made. It was the path of least resistence to make variables reachable from everywhere within the program. I was told that I should have made variables non static and pass around the instance of the class to which these variables belong but now I am too lazy to rewrite the code. However, at least now I think I see why that was the prefer way of doing it even though if you are a beginner it can seem like an unnecessary complicated way to do it (as opposed to just making variables static). Also, I thought that by making variables static I was saving memory (yeah, saving like 40 bytes of memory, good job me). Because if I pass the instance around then I would have a lot of pointers pointing at the same thing. So, I was like, let's just use static then, no unnecessary memory consumption! (I saved couple of bytes of memory yay, I am so good and I see what matters in the program!). Some person on the Internet told me that if I want several chess match to play simultaneously, my architecture fails, while the approach with non static variables with passing around the instance of the class to which those variables belong can do the job. Yeah, I think I see his point, but I am too lazy to rewrite the code. I will keep that in mind for the future. Another experienced programmer told me that a lot of the time if you declare something static you shoot yourself in the foot and I thought "but why". Then I realised that in another Java project I did shoot myself in the foot by putting static in the certain places in my code and the reason was quite similar as in the chess example. It was a server-client kind of project. If I wanted to have several servers running at the same time, my approach didn't work because I used the word static somewhere where I shouldn't have.
    Another thing which I as a beginner learned I was doing wrong is that I didn't use constants enough so my code often times has too much random looking numbers which will probably just look confusing to someone else looking at my code.
    It is funny because when I wrote the chess program 2 months ago I thought my code was great and just 2 months later I kind of think at least parts of my code are crap. It will be interesting to see what I will think about that chess program a year from now. Probably I will think it is total crap.

    • @MichaelMorguarge
      @MichaelMorguarge 2 роки тому +3

      Static used in moderation for utility classes if fine. Static on most things or everything for a large project is not good. There is a time and a place for lots of static (small example projects) and non-static (medium to larger projects). Static also effects reduces your ability to test (Testing/Mocking in C# is not nice with static methods) with the number of libraries that support the static-design programming. Unless you are going for a specific architecture, you are limiting the possibility of expanding on what you are working with and saying "this is the last iteration of this application. It is perfect now and forevermore.".

    • @AdroSlice
      @AdroSlice 2 роки тому +6

      Dogmatic OOP is horrible anyway, a lot of the time if static-everywhere does suffice that stuff should really be straight procedural code

    • @MichaelMorguarge
      @MichaelMorguarge 2 роки тому

      @@AdroSlice sometimes you feel like you are trying to shave a square peg to fit in a round hole when you use a solution that does not fit the platform you are working on. Whether it is C# and Linux or Static Typing and large long-term projects, it will eventually drive you insane. It is better to not write code you hate for your own sanity.

    • @smrtfasizmu6161
      @smrtfasizmu6161 2 роки тому

      @@AdroSlice Majority of professional programmers use OOP. Why wouldn't you use the OOP way of passing the instance unless you have very small amount of RAM. Static and global variables place limitations on what your program can do, while OOP way of passing the instance around makes the program way more powerful in a sense that program can have several chess matches at once, several servers at once etc, also professional programmers say that if you do it the OOP way, there is less problems with race conditions, several functions modifying the same variables etc. compared to using global variables.
      This is what experienced programmers said. They all wanted me to write OOP over global variables.

    • @AdroSlice
      @AdroSlice 2 роки тому +4

      @Smrt fašizmu I'm not arguing against objects in programming at all, but the dogmatic OOP way of trying to mangle everything into a class or method is actively detrimental to your code quality, forcing more boilerplate and requiring more resources for no practical reason.
      Sticking blindly to a paradigm because of an echo chamber extolling its virtues is not something anyone should strive for. In fact, I believe the very notion of separate paradigms is somewhat misguided. Functional, procedural and object-related programming features all have their strengths/weaknesses, and can, and really, *should* be mixed.
      Btw, I'm a professional software engineer, and I use a lot of Go and JavaScript at work, but I don't think I'm biased here as C# remains my most comfortable programming language (which until recently very much tried to enforce OOP).

  • @iaobardar3452
    @iaobardar3452 2 роки тому +10

    I’d love it if you made a rendering architecture video! I’ve been trying to figure out how to use OpenGL in my free time, and been stumped by how to make it more abstract and less hard coded. Right now I just have it hard coded directly in the main loop (really bad design) because I’m using C and have no idea what sort of structures to make to make it work. Am I supposed to make stuff global, and if not, what? Malloc meshes and point to them in an global or static array? Having a tutorial or explanation of how to make a better and more expandable system would be epic!

  • @GamesWithGabe
    @GamesWithGabe 2 роки тому +10

    I don't get why people prefer singletons to just declaring a global variable. The only reason I can think of is you can control the lifetime of the object, but if you're in C/C++ you can just make the global variable a pointer.
    I feel like singletons were created to address the common issues of having too much global state. But that state is still global.
    I also think that turning the variable into a private member and passing it in through a constructor is still pretty dumb, because you haven't changed anything, you just moved the dependency to a different place. In my experience, if you're exposing a lot of state globally it's just because you have a fundamental issue with the way your code is architected. Instead of automatically jumping to a design pattern like a singleton or using an IOC or something, I think more programmers should ask themselves why the dependency is there in the first place, if it's necessary, and if it is necessary is your code fragmented across different units for some reason?

    • @user-dh8oi2mk4f
      @user-dh8oi2mk4f 2 роки тому

      Definitely agree with this

    • @DFPercush
      @DFPercush 2 роки тому +1

      A singleton is basically a namespace. Never understood why people liked them. I personally am not too religious about globals, at least for quick hack projects, but you make a good point about identifying dependencies in your architecture.

    • @CyrilCommando
      @CyrilCommando 2 роки тому

      It's just another C# case of designing a pointless alternative to something incredibly simple. See: Properties. Interfaces.

    • @solaris5303
      @solaris5303 2 роки тому

      ​@@CyrilCommando
      Properties are just syntactic sugar that save space and time compared to Get/Set methods. Interfaces are incredibly useful across countless scenarios - like pure abstract classes, except for a system that (by design) doesn't have multiple inheritance.

  • @jjxtra
    @jjxtra 2 роки тому +3

    Biggest advice: Separate your scene hierarchy, scene objects and rendering into completely separate classes and interfaces. Renderer knows how to render scene objects, Scene knows how to store and manage scene objects. Scene and scene objects don't need to know a renderer even exists.

  • @okcharles7
    @okcharles7 Рік тому +1

    Nullable reference type is a compiler service rather than a type.
    You can call the service by post-fixing '?" to the variable you want the compiler to watch your code mistake.
    from time to time, for a short time, you can turn it off by post-fixing '!'.
    That is different from nullable value type, which wraps a value type and expose the underlying value thru "Value" properperty.
    Nullable reference type doesn't cost you at all because it is a compiler service.
    However, it gives you amazing relief and safety to your code.
    It is the very cure for the all the madness from the implicit null initialization.
    It is one of top three adorable things in C#, along with ref( and out) and delegate.

  • @selore4865
    @selore4865 2 роки тому +11

    I'm over here, 26 years old, and I'm still struggling to figure out DirectX...

    • @AcridDragoon
      @AcridDragoon 2 роки тому +3

      Fr tho smart kid

    • @Thomahawk1234
      @Thomahawk1234 2 роки тому +9

      Don't worry. If you keep at it you'll eventually be a 27 year old who figured out DirectX

    • @hawks3109
      @hawks3109 2 роки тому +2

      all good, everyone has their own pace. The kid in this review has a lot of knowledge for his age, but I imagine it's pretty scattered (as evidenced by this code). He probably doesn't have the strong math background to really understand what's going on, just how to get the code and modify it a little bit in some places. Of course for his age this is incredibly good, but there is still a whole ocean of knowledge out there he hasn't touched.

    • @XxxGuitarMadnessxxX
      @XxxGuitarMadnessxxX 2 роки тому +3

      Don't know if it'll make you feel better, but I only started dabbling with programming when I was 25 (28 now) and things like DirectX and Vulkan will definitely come easily to you once you do other types of projects and get a feel for how data should really be processed and transferred - this is just presuming you're like me who started with no knowledge of programming lol But in all seriousness, just do what you've been doing and chunk things out into smaller bits - you got this =D
      I'm going to pull from a personal project of mine as an example - I saw Cherno use spdlog a while back and decided to try spdlog out (it's absolutely fantastic and reeeaalllyy fast). I then started out writing a wrapper but was having a lot of fun with extending it, that I ended up writing my own logging framework inspired from spdlog (it's nowhere near as robust and only handles the terminal, single files, and rotating logs at the moment) but a lot of the fun came from trying to make it faster than spdlog - which I've done just that (40% faster terminal: with color and stdout, 90% with stderr/color, 105% with stderr/nocolor, 45% file, and ~50% for rotating logs).
      So the point of my rambling on and on there - if you just find someway to make DirectX or any graphics API programming fun - you'll just lose yourself in the learning process and come out as a strong and knowledgeable person in that context. Rambling finished lmao Best of luck!!

    • @bluesillybeard
      @bluesillybeard 2 роки тому

      @@hawks3109 I'm a 16 year-old, and actually can relate to that. I myself have a lot of holes in my knowledge, and it's probably going to be a loooong time before I actually figure out what a transformation really is doing, or how to properly organize my code, or even just how to import a library in C or C++.

  • @fredvin27
    @fredvin27 2 роки тому +4

    +1 for the renderer architecture. Great videos, great review, thanks a ton for the content !

  •  2 роки тому +2

    Nullable is really useful, especially when the TreatWarningsAsError flag is switched on. Because your code won't even compile when you forgot to assign a value to the variable, which is intended to be not null. It saves a lot of time being lost during compilation/test/debug/fix/retry/foo/bar. And we all make such mistakes often.

  • @siddharthasarmah9266
    @siddharthasarmah9266 2 роки тому +6

    The flawless switch to the sponsor moment was brilliant ;)

  • @Chris-dx6dw
    @Chris-dx6dw 2 роки тому +1

    Its a static member of the class. If you didn run Main, then it will always be null. Now in this case, we always run Main. But if this was another class, you may never run the method that initialises it. So any use of it would get a null ref exception. So this is to let us know that null is a possible value.

  • @NR1612
    @NR1612 2 роки тому +5

    That Brilliant segue got me 🤣I love that

  • @VerdASMR
    @VerdASMR 2 роки тому +2

    That sam guy really knows his bloom ;)

  • @zimcoder
    @zimcoder Рік тому +2

    He encounters a new concept and because fear of change "this is why I stick to C++"

  • @chalkchalkson5639
    @chalkchalkson5639 2 роки тому +3

    I think it's really cool to see some other languages highlighted! The most interesting parts are the general CS lessons anyway and not "hey this way of doing it in c++ is slightly nicer". Reading code in a language you're not 100% familiar with also also a really good skill to have and so might be neat to showcase that :)
    Maybe you could even branch out and review some code that's done in even more different languages like Java (channel history and all that), FORTRAN or Python.

  • @samsonmayeem8409
    @samsonmayeem8409 2 роки тому

    At 8:30, "so if I understand this now". I say this usually in lectures when confirming my understanding. I have recommended your tutorial for my trainees, and they are excited too. You are my boss. Greetings from Ghana, I love you the Cherno.

  • @PostNoteIt
    @PostNoteIt 2 роки тому +1

    I'd like to see right after the end of your analysis another run of the program where you point at the effects you've seen the implentation of in the actual code. Like going full circle, starting with the program, exploring the details, getting bck to the program and putting the details into perspective.

  • @Meoiswa
    @Meoiswa 2 роки тому

    The idea behind non-nullable reference types is that, when you're working with an "object driven design", the variables for said objects are no longer "pointers to regions in memory" (that could be empty), but rather "things". Having "things" not allowed (by default) to be null allows writing less strict code (no need to null-check for safety everywhere) without creating less safe code (by guaranteeing by contract that things will have value).
    From a very top-level point of view, its basically syntax sugar for adding null checks on setters/getters/parameters/etc.

  • @TheXenoEnder
    @TheXenoEnder 2 роки тому +1

    Nullable reference types is for static validation (find errors at compile time instead of runtime)

  • @taylorswe
    @taylorswe 9 місяців тому

    To be clear anything NOT marked as nullable can still be null in some edge cases...
    The question mark is more of a DX thing than a compilation concern (note that not including a question mark creates a warning, not an error).

  • @zhh174
    @zhh174 2 роки тому +1

    You can use sln with dotnet cli on any platform. c# is cross-platform and open-source now.

  • @DoorThief
    @DoorThief 2 роки тому +1

    It'll show the nullable warning for a field If it isn't initialized in the constructor. You're running from the main method where it's assigned to then, but since it's not the constructor you're going to see the warning.
    Recently added nullable has a setting in the csproj. The idea is you have to be more explicit and careful with things that may not have a value when you try to use them, so that you'll hit less Object Reference Exceptions If you were to access a property or something for a null value

  • @vast634
    @vast634 3 місяці тому

    If something just exists once in the runtime, or is just created once, it totally fine to just use static. Its shorter, easier to unterstand and avoids boilerplate code with passing references around. If you write an API or have potentially several instances running, dont use static.

  • @peter1745dev
    @peter1745dev 2 роки тому +1

    Love the fact that you're doing C++ as well as C# reviews :) I really like C# as a language. Wasn't aware that reference types should use the nullable operator nowadays, doesn't actually make a lot of sense to me since reference types can be null by default, I get it for value types since they're not nullable by default

  • @Beatsbasteln
    @Beatsbasteln 2 роки тому +1

    thanks sam for this code review

  • @dcmayo
    @dcmayo 2 роки тому +1

    I would LOVE to see more C# on the channel.

  • @Chiramisudo
    @Chiramisudo 2 роки тому

    Haha, well done on the sponsor ad. You just snuck that right in there during the clone. Smooth! 😋

  • @jonteguy
    @jonteguy 2 роки тому +3

    Taking code without giving credit to the proper author of it is very shady.
    Again it's opensource, but it should still be referenced, obviously.
    Stuff like this makes me question if people wrote anything at all, unfortunately.

  • @PatrickHoodDaniel
    @PatrickHoodDaniel 2 роки тому

    At the age of 16, I wish I was at his level. When you say massively fractured, do you mean that is refactored to a needless point? I typically refactor only when a set of code is duplicated, or there is a need for object-oriented use, like inheritance.

  • @KamillaMirabelle
    @KamillaMirabelle 2 роки тому

    The nullable postfix, helps the compiler in the optimization process, it make runtime information, compile time information, which give the compiler clues about runtime behaviour. If you flag a variable (here a pointer) as not null able, the compiler can eliminate that check, this will lead to some performance gain

  • @unlxck3255
    @unlxck3255 2 роки тому +1

    I really hope that i will have the knowledge about these stuff like you have. Its so impressive

  • @mihairadita9313
    @mihairadita9313 2 роки тому +5

    When will you continue with the game engine series? I really want to see more physics implemetation especially in 3D

  • @bmryner90
    @bmryner90 2 роки тому +1

    Title should've been
    "16 year old breaks The Cherno"

  • @vincentvoillot6365
    @vincentvoillot6365 2 роки тому +3

    I write my first line of basic in the early 90', and let me tell you for a 10 years french old boy, finding resources or softwares was the hardest. Maybe 2-3 books in the local library and compilers weren't free (mostly C), every thing on floppy. Bigest issues IMO, it's to begin with an strict OO langage (specialy java, find it aweful ).
    Better begin with C or Javascript even, start with basic control flow and structure, then with that knowledge discover class with c++ or prototype and class with JS, then design pattern . Once you understand those, you can read and write almost any langage with google helping for the syntax.
    A serie on design pattern would interest me greatly.

    • @MichaelMorguarge
      @MichaelMorguarge 2 роки тому

      You need both sides of the coin or else you will force scripting-language principles into object-oriented languages and vice versa. If you get an understanding of both programming ideologies (no matter which side you start with), you will know when you can and cannot apply certain language principles to certain things.
      Consider the coding standards per language. An example that extends past the scripting vs. OO barrier is where Java wants people to use formats for method names like "getName" but in C# they want people to use "GetName". In other languages, you may have to use "_getName" or "#getName". The amount of semantics and unique design decisions per language is incredible considering how one small detail can change how language operates (pass by value vs. pass by reference).
      Overall, there is still much to learn for every programming language that seems similar but handles things in a very different way under the hood that makes one It's what makes programming fun.

    • @vincentvoillot6365
      @vincentvoillot6365 2 роки тому +2

      ​@@MichaelMorguarge Java enforce oriented object and is very strict about his syntax.
      And you can implement class in C (in JS class are simulate by prototype) or any paradigme, High level programming is mostly syntaxic sugar.
      About coding convention, you can name your getter setter as you like. But following a common naming convention help to make it readable. (Eclipse do the heavy lifting for java)
      There is no "scripting-language principles", Java was and still is "interpreted", C++ is a compiled langage but can be interpreted (cf Cling ).
      Beyond that aspect of executing your code, programing paradigme are the same across all langages.
      All Class oriented langages have constructor, destructor, super public and private method. (Java, C++, Rust, Python, Scala, Typescript, PHP)
      You write a while in JS or PHP, it's mostly the same syntax.
      It take me one week to be efficient (not googling the syntax every two line) in PL/SQL and it is ugly to read and write as f*ck.

    • @MichaelMorguarge
      @MichaelMorguarge 2 роки тому +1

      one of the things I try to follow is to leave the code cleaner than when you started working with it. So whatever coding convention that is defined for the language or IDE you are using will technically be the cleanest standard to use unless the setup of the language is a mess. Doing the best you can to put produce clean and efficient code that follows the expectations of the original intent of the current iteration of the language/ide goes a long way for immediate and long-term maintenance.
      I agree that some languages will leave you writing code that you never wanted to write to work around shortfalls or bad architecture. Pl/SQL is a nice addition to SQL but it has a ways to go before in terms of cleaner implementation.

    • @vincentvoillot6365
      @vincentvoillot6365 2 роки тому

      @@MichaelMorguarge I don't disagree with you on the importance of following convention, official or proposed by the IDE.
      But the most important is not the convention in itself, it's the logic behind it and how to think your code.
      The case made by Chernot, for example, separate the renderer code.
      If you cannot write good code on notepad, no IDE or convention will help you to structure your code, mainly make it readable, not the same thing.
      In school i learned about UML, it's laborious but sanity-saving on a big project, from that you can even generate a skeleton code ready to be complete.
      I liked to have a bird-eye-view of what i'm doing and how i'm doing it.
      My grief with Java is the stupidity to force everything into the Class for the sake of it.
      I still have nightmare about the three flavors of String.
      As for PL/SQL, it's mostly influence by pre-C++ langage like ADA or PASCAL.
      It's kind of oriented object with the package. Writing a simple loop bring me back to the late 80's.

    • @vincentvoillot6365
      @vincentvoillot6365 2 роки тому

      @@MichaelMorguarge FYI, you can't implement a cleaner pl/sql. It wouldn't be PL/SQL.
      Don't mistake implementation and specification.
      The spec contain the grammar (keyword like While, super, loop ..) and syntax ( simply put where, how and when you use { } ( ) , ; , etc )
      Ex : Ecmascript is the definition of the javascript langage, typescript is an other langage based on ecmascript with his own specification.
      Scriptmonkey, V8, Chakra, ducktape, quick.js are all Javascript interpreter, they are implementation of the Ecmascript specification.
      Or C99 is a specification as C11 ( an extention count as a different spec, C99 compiler can't compile C11 news features, but you can implement them in C99) and VS, clang and gcc "'implement" the specification into the compiler.

  • @hailsatyr
    @hailsatyr 2 роки тому +2

    Jesus, I didn't know shit when I was 16. The competition is getting ridiculous.

  • @buggyspeaks7349
    @buggyspeaks7349 2 роки тому

    Yes! Please do make a video that shows how rendering should interact with oop. The biggest obstacle in deciding how to set up my own engine has been deciding where to put the actual opengl functions without making the Renderer class insanely complicated.

  • @coolguyflex
    @coolguyflex Рік тому

    Nullable reference types are great. If you had waited another second, the static analysis would have warned you that you were about to call a method on an object that could be null.

  • @tanmaypanadi1414
    @tanmaypanadi1414 2 роки тому +1

    38:45 I don't know anything about it . but I would love more videos about it.

  • @oivinf
    @oivinf 2 місяці тому

    C# is my main language so this is very interesting! That being said, I partially watch you to get more into C++ so both are good

  • @criptych
    @criptych 2 місяці тому

    Technically you can start a variable name with an underscore in C++; it's still a legal name, but the pattern is "reserved" for system names. And I'm pretty sure (though could be remembering it wrong) that only applies to global names, not class members.

  • @speedracerx713x
    @speedracerx713x 2 роки тому

    The nullable reference indicator forces developers to acknowledge possible runtime null references they may have otherwise missed. IT's basically shorthand for saying "Yeah, I'm aware of this situation".

  • @jiiiiim_xyz
    @jiiiiim_xyz 2 місяці тому

    I've watched half your youtube channel and have been attempting to learn for 2 years or so.. and have just about learnt how to make Pong. This 16 year old kid need not worry about finding a job.. wow I feel stupid.. Thanks for all the videos! I should probably sign up to Brilliant so it sinks in..

  • @ByteSurgeon3749
    @ByteSurgeon3749 2 роки тому +1

    Null is bull. Basically, nullable means it’s an object or null. It’s essentially a union type. An object shouldn’t have ever been nullable by default, because null is a different thing to an object. Returning null instead of an object is laziness, if you need to return null you should be handling it yourself, not passing it off to the caller to handle. Not my problem is not a good way of writing clean code.
    You call my method expecting to give you back a SomeBusinessObject, but you gave me bad data so I’m going to return null and expect you to figure out why. Without doing that, the best I can do is return null too. You then end up handling null all the way up the call stack just because you couldn’t be bothered to find an elegant way to handle not getting the right input.
    When you consume other people’s code you shouldn’t need to know how it works, just that it works. If you’re returning null with no explanation, I’m going to end up having to figure out how your code works to handle your preconditions myself. Encapsulation is important and if you don’t use it, it defeats the object (no pun intended) of OOP.
    Of course, you may find null useful for a very small subset of problems where you don’t want to expose the issues you have with my input, for example in auth. But find a better way than null, please. Null just means nothing, and I shouldn’t have to figure out whether I gave you bad data or if my your code is broken, just tell me.
    There’s nothing more annoying than some API returning null. Tell me why you the call failed please.
    By the way, I’m assuming you returned null because something went wrong in your method, I really can’t think of any other reason you’d return null.
    Also, welcome to UA-camOverflow. Please be nicer than StackOverflow, and rant over.

  • @KieranDevvs
    @KieranDevvs 2 роки тому +18

    You missed the compiler warning because you were going too fast. If you declare the type as non null and then invoke a member without instantiating, the compiler analysis will warn you that this code is unlikely to succeed.

  • @rp8133
    @rp8133 2 роки тому

    Hi Cerno, first thanx for your videos over the last years. I love to consume them and to learn from. Concerning the way programmers write their code one could easily start a holy war :-) Within the team I've been working for more than 2 decades we stumbled over this problem too. We negotiated our 'do's and 'dont's and the work was fine. We constantly work with C++ and C# (and C++/CLI). So we decided to use the most common notation for each language. So, as an example for C# class fields we use the leading underscore camel case rule (e.g. 'double _axisVelocity'). For C++ in general we decided to hold it near to what the stl guys do: all lower case and syntactically delimited by underscore. For C++ class fields we are not really unanimous. Some prefer m_* or _*. I prefer *_ which should never collide with C++ internals (e.g. 'double axis_velocity_'). But, in the end the only thing that counts is: CAN I READ IT (3 months later) and CAN OTHERS READ IT.

  • @bluesillybeard
    @bluesillybeard 2 роки тому +1

    I would absolutely love to see a video about creating a good simple OpenGL rendering architecture.

  • @Kitulous
    @Kitulous 2 роки тому +4

    c#8's nullable reference types are a blessing to null safety
    it's the same in Kotlin, you cannot have a null value in T, no matter what T is (class, struct, enum, whatever)
    that way you will only get null reference exceptions if you opt-in (by using the postfix !)
    for example:
    MyClass x = null; // compile error
    MyClass? x = null; // fine, you need to check for null now
    MyClass x = null!; // you shut the compiler up and if something tries to reference x you will get a NRE

  • @DioArsya
    @DioArsya 2 роки тому +1

    Nullable features like that really helpful, especially on js & ts, can't wait to uss that on cs

    • @HermanWillems
      @HermanWillems 2 роки тому

      NULL should be forbidden. It's the biggest mistake made in programming history. It should be deleted from every programming language ASAP. Rust programming language has no NULL, and it works perfectly and without all those shit null mistakes. Null is just total bullshit. The inventor and creator of NULL regret what he has made. (He said this himself)

    • @undefinedchannel9916
      @undefinedchannel9916 9 місяців тому

      @@HermanWillemsThe nullable features basically do what Rust does. You get warnings (or errors, if you configure it) if you don’t mark something as nullable or you try to use something nullable in a way that would cause a runtime error.

    • @HermanWillems
      @HermanWillems 9 місяців тому

      @undefinedchannel9916 not a compile error? Why not a compile error. While runtime. U want to catch things in compile time. Runtime is not good.

  • @quintencabo
    @quintencabo 2 роки тому

    That was one of the most smooth sponsorship inclusions I have ever seen

  • @marytooker956
    @marytooker956 2 роки тому

    I believe moving the initialization of _window to a static constructor would have removed the intellisense warning.
    It was just pointing out that _window was a non-nullable ref type, but during the lifetime of the Program class (i.e. right after construction prior to invoking Main) the _window reference IS null.

  • @zmania101
    @zmania101 2 роки тому

    That sponsored segment transition was so cheesy, I love it.

  • @juhotuho10
    @juhotuho10 11 місяців тому +1

    Copying code from someone elses codebase like a true programmer
    he is learning fast

  • @idc20627
    @idc20627 2 роки тому

    we just witnessed how cherno learns and explains a specific feature of c# he never encountered both at the same time

  • @ultimatesoup
    @ultimatesoup Рік тому

    I write game engines and tooling as well (27 years experience). The main thing to get correctly is that all the high level "manager" components (e.x PhysicsManager , EventManager, ResourceManager, Memorypool, RenderManager, AIManager, etc) typically need to be accessible from anywhere. The two primary architectures I see for this is to make them Singletons or to contain them all within a top level class as statics. I prefer the statics approach. Typically its a resource drain to have every renderable or AI capable component have a copy of the corresponding manager. I really dislike making them singletons because it has more overhead for the dereference and call to getinstance().

  • @shottyman6013
    @shottyman6013 2 роки тому

    That segway to brilliant was genuinely smooth

  • @CodeNova
    @CodeNova 2 роки тому +4

    Kudos for figuring up so quickly what is not-null-able in C#10. And you explained pitfalls on window.Run() if window is null. Thumb up !

  • @minastaros
    @minastaros Рік тому

    In C++ thinking: the _window is not like a class instance, but similar to a (C++) pointer or a reference. A pointer would be the nullable variant with "?", whereas the reference is guaranteed to "point" to a real instance.

  • @C3NTesports
    @C3NTesports 2 роки тому

    I barley know anything about programming but this was in my feed but my goodness this is fascinating 🤯

  • @localatticus4748
    @localatticus4748 2 роки тому

    The new nullability annotations are fantastic, honestly, especially since the compiler can check branches to see if things have been initialized or null-checked previously as well so you don't have to explicitly handle null from then on either even if the type is marked nullable. I use it everywhere I can for documentation of my intent and to get those flow control warnings from the compiler. I only get null reference exceptions now when I'm trying to be cheeky and throw something together without thinking about it first.

  • @axellara3353
    @axellara3353 2 роки тому

    Congratulations! That engine looks really nice!!

  • @narumikazuchi
    @narumikazuchi 2 роки тому +2

    Let me explain the reasoning behind the nullable reference types. If viewed from a compilers perspective it does effectively nothing. However that isn't it's purpose in the first place. It's intended to visualize the intend of the code to the programmer. Example, you want to utilize a method of a class from a third-party library and you see a nullable reference type as a parameter of that method (like SomeMethod(Someclass? parameter)). This method signature implies to the programmer, that you CAN pass it a null value without the compiler throwing an exception. Meaning that as the creator of the third party library you are communicating, that this reference type parameter is allowed to be null, whereas if the signature would be like SomeMethod(SomeClass parameter) the programmer who consumes the third party library knows at a glance that passing null would likely yield an exception.
    I hope I could shed some light on the topic of nullables for you or anyone else, who doesn't know why they exist.

  • @DylanMatthewTurner
    @DylanMatthewTurner 2 роки тому +2

    Despite being quite different than C#, another language that has a really great IDE integration tool is Rust imo.

  • @jurikristjouw
    @jurikristjouw 2 роки тому

    Thank you! I am so glad you were flabbergasted with the nullable reference question mark.. It also does not make any sense to me as to how this improves quality... There are more of these gizmo's these days.

  • @blackcoder41
    @blackcoder41 2 роки тому

    I can relate to that reaction on null references coming from Java/JavaScript to Kotlin/TypeScript hahaha 😅
    This is how Kotlin sells this feature:
    Kotlin's type system is aimed at eliminating the danger of null references, also known as The Billion Dollar Mistake.
    One of the most common pitfalls in many programming languages, including Java, is that accessing a member of a null reference will result in a null reference exception. In Java this would be the equivalent of a NullPointerException, or an NPE for short.

  • @philipmrch8326
    @philipmrch8326 2 роки тому +1

    Use dependency injection alongside singletons. This kind of hides the fact that it's a singleton

  • @jansvoboda8940
    @jansvoboda8940 10 місяців тому

    This nullability can be turned off in project configuration file. It can be also turned to mode, when everything what is by default green underlined is an error.

  • @zhh174
    @zhh174 2 роки тому

    Nullable reference types are just compiler annotations. So compiler would give a warning if you try to use that nullable type without checking for null.
    Window? window;
    window.Run(); // this will generate a warning
    if (window != null)
    {
    window.Run(); // this will not generate a warning
    }
    A shorthand for the above code is
    window?.Run()
    This is very helpful because you won't ever get a runtime exception for null values. Most modern languages have this feature from the beginning.

  • @infinityminuszero
    @infinityminuszero 2 роки тому

    You could've been more encouraging to the 16 year old that sent you the code. Few 16 year olds can do this kind of programming, let alone a "hello world".

  • @sigmareaver680
    @sigmareaver680 2 роки тому +1

    My only experience with C# really is with Unity. On the game I'm currently writing (in C++), I plan on using Lua as a scripting language.

  • @GonziHere
    @GonziHere 2 роки тому +1

    the point of explicit nullable is that now, you can actually have a method that takes a class as a parameter but since is not nullable, you don't have to do the nullcheck everywhere... you can easily differentiate between the "initialization code" that needs to check these things and the "actually running code" that doesn't anymore. You can, in most of your codebase, act with objects the same way as you would with integers, or, well, references with cpp.
    edit: "this is why I stick to cpp" - funny, since it's something I would love dearly in cpp. What would be your equivalent of doing it? using pointers for "nullable objects" and references when in "nullable not allowed anymore" parts? thanks.

    • @HermanWillems
      @HermanWillems 2 роки тому +1

      NULL is the biggest mistake in programming history. It should be deleted from Java and C#. ASAP.

  • @glewfw7989
    @glewfw7989 2 роки тому

    more about cherno learning c# PLZ
    a heck lot of ppl will relate with you

  • @worzell5169
    @worzell5169 2 роки тому +1

    Could’ve at least played the amugus music when you found out the bloom was sussy

  • @andersmalmgren6528
    @andersmalmgren6528 2 роки тому

    If you move the declaration to the constructor you can ommit the forgiving operator.. if you write solid code you should try to have as few nullable members as possible

  • @sps014
    @sps014 2 роки тому +1

    Great video looking for more C# & C++ content

  • @Christobanistan
    @Christobanistan 2 роки тому

    I really like C#'s new(ish) non-nullable reference types. I turn it on in all my projects now.

  • @ahsanullah6326
    @ahsanullah6326 2 роки тому +1

    variable names starting with _ is allowed in c++ from forever dude

  • @alexkhazov7264
    @alexkhazov7264 2 роки тому +6

    I would love to see the simple opengl architecture example! :D

  • @47Mortuus
    @47Mortuus 2 роки тому +1

    25:56 The ECS mentality? Big step for optimization? What are you talking about? It's poor man's (not really) ECS, where we still have an ARRAY OF STRUCTURES and not a STRUCURE OF ARRAYS. And especially in C#, each class instance is just a pointer. An array of instances stores pointers and thus every array element is a cache miss in this implementation, still - apart from this not ECS in the first place, where you don't operatore on instances of classes but rather instances of DATA MEMBERS (you iterate over each "Person"s "Age" variable in one go but do not load in their "Home" pointer, "FamilyMember" Array etc., allowing for VECTOR CODE for the "Age" variable calculation)

  • @acidiclight
    @acidiclight 2 місяці тому

    I wish Cherno didn't name an engine "Sparky" so I could use that name aaaaaaaa