Minecraft Clone in C++ // Code Review

Visit brilliant.org/TheCherno to get started learning STEM for free, and the first 200 people will get 20% off their annual premium subscription.
Patreon ► / thecherno
Instagram ► / thecherno
Twitter ► / thecherno
Discord ► / discord
Code ► github.com/Isti01/glCraft
Send an email to chernoreview@gmail.com with your source code, a brief explanation, and what you need help with/want me to review and you could be in the next episode of my Code Review series! Also let me know if you would like to remain anonymous.
Chapters:
----------------
0:00 - What we're looking at today
6:55 - Playing the game
8:55 - Project structure and initial thoughts
10:30 - Local static singleton
14:10 - How to organize a class (my style)
17:43 - The math
19:22 - Ray casting and how I would change it
23:55 - Designing code structure
28:08 - Other notes
29:23 - Some weirdness and how to write clear code
35:22 - Vertex packing and shaders
This video is sponsored by Brilliant.
#CodeReview

Пікірлер: 363

  • @TheCherno
    @TheCherno2 жыл бұрын

    Hope you all enjoyed the video! Sorry about Ghost Cherno 👻... have you made a Minecraft clone before? How did it go? 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!

  • @user-ph5cu2tr8d

    @user-ph5cu2tr8d

    2 жыл бұрын

    Minecraft!😆

  • @TheShadoDragon

    @TheShadoDragon

    2 жыл бұрын

    I'd say Ghost Cherno has it's positives sides as well: You can see the code below the camera. ;)

  • @rob-890

    @rob-890

    2 жыл бұрын

    Why do you ask for comments and then not reply? 😋

  • @-TL-15

    @-TL-15

    Жыл бұрын

    I want to ask how it is that for the video 3D Game Programming - Episode 4 - Drawing Pixels! when I run it I don't see anything there and I proceed exactly the same :(

  • @greatcesari

    @greatcesari

    Жыл бұрын

    Your tone sounded pretty harsh, considering the maker said they're just learning.

  • @not_herobrine3752
    @not_herobrine37522 жыл бұрын

    "the only design pattern a programmer needs to know is ctrl + c and ctrl + v" -sun tzu, the art of code

  • @adamhelberg9228

    @adamhelberg9228

    2 жыл бұрын

    Hipity hopity your code is my property -Dani

  • @nakumjay

    @nakumjay

    2 жыл бұрын

    Bruuuuuuuuuuuuuuuuuuuh

  • @ShredBird

    @ShredBird

    2 жыл бұрын

    Sun "Microsystems" Tzu

  • @Highwind_

    @Highwind_

    2 жыл бұрын

    @@ShredBird This would explain Java

  • @superscatboy

    @superscatboy

    2 жыл бұрын

    Virgin copypaste Vs Chad *macros*

  • @lukefidalgo8154
    @lukefidalgo81542 жыл бұрын

    I think every programmer that's interested in making games from scratch will always go through that phase where they want to make a Minecraft clone lol

  • @amadeusk525

    @amadeusk525

    2 жыл бұрын

    Minecraft is just a great concept, programming-wise. It's impossible not to have fun while trying to code it, or just trying to understand how one would do so

  • @makotomiyamoto5249

    @makotomiyamoto5249

    2 жыл бұрын

    Recreating Minecraft allows to you to explore many parts of the development process and touches a lot on optimization because of how performance-draining a voxel engine otherwise is.

  • @eucalypt444

    @eucalypt444

    2 жыл бұрын

    @@makotomiyamoto5249 theres no voxel engine in minecraft lol

  • @makotomiyamoto5249

    @makotomiyamoto5249

    2 жыл бұрын

    @@eucalypt444 Is this supposed to be joke? Obviously, since Minecraft is engineless, it’s engine is *internal*.

  • @eucalypt444

    @eucalypt444

    2 жыл бұрын

    @@makotomiyamoto5249 wrong. minecraft uses BrownEngine

  • @toffeethedev
    @toffeethedev2 жыл бұрын

    love higher-level design talks like this, optimisations are usually specific to the 1 program, but knowledge about code architecture will never stop being useful

  • @bloodgain
    @bloodgain2 жыл бұрын

    Additional comments (and disagreements with Cherno's comments): - For a better understanding of the Application instantiation argument here, just look up why Singletons are considered a bad practice. If you're going to use a Singleton in C++, though, _always_ use the Meyers Singleton (thread safe), which you did. On this count, Cherno is wrong and going against widely-regarded best practice. He is right that it's subject to the Destruction Order Fiasco, but if you insist on a singleton, you live with that. Just don't have singletons that depend on other singletons -- as if singleton wasn't a bad enough design! There is another pattern called Leaky Singleton that avoids destruction entirely, but one, if you need that you have a bad design, and two, if you're going to go through the trouble of learning how make a good, thread safe, leaky singleton, you'd be better off spending the time re-architecting to get the singleton(s) out of your design. - While it's an architecture argument, I probably agree with Cherno's critique of your Ray class. However, passing the World into the function like that? That's _exactly_ how you avoid Singletons **and** tightly-coupled code. It's called Dependency Injection, one method of Inversion of Control -- aka coding to interfaces, not objects. Good instinct, if not the best use of it in this case. Still, way better than making World a singleton! - Cherno's argument against using explicit is simply wrong. You absolutely should mark all single-argument constructors as explicit. Not doing so can result in accidental implicit conversion, which adds runtime overhead. All such conversions should be made explicitly, usually by calling static_cast or dynamic_cast. Again, this is _widely_ considered best practice. - Why is it called main? Why not? This is an application, not a library. It's probably the IDE's default, and defaults are de facto patterns. Plus, it's just a learning project, and it could always be renamed later. Code reviews should not be nit-picking exercises. - Class layout is a little bit of a style nit-pick, but in this case, I actually agree. This is the standard layout that other developers expect to find. If you declare it as a struct (public access by default), this signals something a little different to another developer that this is more datatype than functionality, will probably be entirely public, and you can leave off the "public" declaration. Think of these as de facto standards. - Cherno doesn't call you out for not separating your code from your declarations, but I will. If you're going to enclose all your class's functionality in one file, it should be a header (.h) file. But still, separate your code from the declaration, either as "inline"d functions below the class declaration or in a code (.cpp) file. The _possible_ exception is simple one-liners like getters/setters that are only an assignment/return, but separate is better even then. This is another de facto standard, and most style guides enforce it. - If you have a destructor, either write the copy and move constructors and assignment operators, or remove them with "= delete". If you write any of these, you should write all of them. This is called the Rule of Five (formerly Rule of Three before move semantics were added in C++11). - Your "chunks" map is duplicated. Maybe that actually fits your design well, as long as you're not carrying 2 full duplicates of all of them in memory, but it does mean that *the map type is declared in more than one place.* Abstract that out. At minimum, use a typedef, but if "chunks" has responsibilities beyond what unordered_map provides, then it should be its own type with functions. A clue here would be if you're repeating code to operate on chunks in multiple places. - Overall, though, great job. Some of it is pretty clever, actually. Maybe read a style guide or two and check out some C++ best practices guides. Scott Meyer's "Effective" series of books is highly recommended, but there are some good free guidelines and talks out there, too.

  • @miguelguthridge

    @miguelguthridge

    2 жыл бұрын

    That was really informative! Thanks for taking the time to write it. I'm gonna be learning C++ properly (messed around with it in high school) next term at uni so it's really interesting reading all the comments on how C++ code should be written from a stylistic standpoint.

  • @Bobbias

    @Bobbias

    2 жыл бұрын

    @@miguelguthridge universities generally end up teaching horrible code style, so it's good to have a handle on what constitutes good code style before heading in :)

  • @andraskmeczo575

    @andraskmeczo575

    2 жыл бұрын

    @@miguelguthridge if you let me add to that the most you can learn is writing actual code, because then you'll encounter problems, look at other people's code, take the best of everything and have a good coding style after a while. Especially if you build a bigger project like a smaller but whole game or a game engine you'll inevitable follow the good practices because it will be easier to use than bad practices (or at least this was true for me)

  • @Astfresser

    @Astfresser

    2 жыл бұрын

    Great explanation and I agree totally, but I think Cherno meant to avoid the singleton just put the object altogether on the main stackframe instead of having it lying around in global scope, which I would very much encourage. You can just pass your world object to every instance in a functional way and never have to worry about threadsafety.

  • @FokinDenis

    @FokinDenis

    2 жыл бұрын

    Thank's for information!

  • @vladimirkraus1438
    @vladimirkraus14382 жыл бұрын

    "explicit" is your friend. Unwanted or unexpected implicit conversions can cause a lot of troubles and hard to find bugs. I always use "explicit" unless I am really 100% sure that I want an implicit conversion for that type. Explicit conversion requires more writing but makes the code much more readable and simpler to reason about. It makes the code more type safe and less prone to errors.

  • @agfd5659

    @agfd5659

    2 жыл бұрын

    It's weird that they didn't make explicit the default now that I think about it.

  • @vladimirkraus1438

    @vladimirkraus1438

    2 жыл бұрын

    @@agfd5659 Yes, it is one the many wrong decisions when designing C++. But back in that time the language priorities were different than they are now. They probably believed that implicit conversions allow for more concise code (which they do) and did not think so much about language safety.

  • @doglitbug

    @doglitbug

    10 ай бұрын

    @@agfd5659 I wonder if the author used CLIon and it suggested this all over the place

  • @migueldejesustavares4168
    @migueldejesustavares41682 жыл бұрын

    You should 100% make your own Minecraft Clone tutorial series. It would be such a good learning resource.

  • @andrewcranston780
    @andrewcranston7802 жыл бұрын

    When doing code reviews, its always good to keep personal 'feeling' or code style debates out. "I just don't like this" isn't a good reason, and doesn't go far in explaining why someone should avoid using singleton for the top level Application class. You could instead go the 'singleton is hard to test' route, and explain how you'd eventually want to write unit tests and instantiate the application inside a test harness.. if its designed to be statically instantiated that becomes hard to do.

  • @kukukudoes458

    @kukukudoes458

    Жыл бұрын

    Point It gets annoying when you tell to not do something but don’t point out why

  • @andrewcranston780

    @andrewcranston780

    Жыл бұрын

    @@kukukudoes458 usually if no actual explanation follows it's because the reviewer is a cargo cult programmer with no original ideas of their own.

  • @jumpingjoy7689
    @jumpingjoy7689 Жыл бұрын

    The reason that there is a lot of "explicit" in the code is that the programmer is most likely using clion, which includes clang-tidy, which alerts you about single argument constructors. it is also why you see [[nodiscard]] aswell

  • @h.hristov
    @h.hristov2 жыл бұрын

    Hi Cherno, could you create your own series on design patterns? I wonder what your take would be on them. Recommendations / pitfalls.

  • @Ezdiess

    @Ezdiess

    2 жыл бұрын

    He just made a rant over OOP and you expect him to make a video about desing patterns? Highly doubt it

  • @h.hristov

    @h.hristov

    2 жыл бұрын

    @@Ezdiess Haha that was the reason I wrote this comment

  • @spikespaz

    @spikespaz

    2 жыл бұрын

    He's pretty bad at design honestly, this whole ray casting thing in the constructor was explained horribly and he took too long to come to the conclusion it should be in the world class. Ideally it should be on a behavior interface that anything that can cast a ray can implement.

  • @Psykorr

    @Psykorr

    2 жыл бұрын

    This is actually a good idea. Not because design patterns are that omnipotent as many think, but to set up a problem for which a design pattern COULD be a reasonable solution. For example, if you have a program that have different modes, perhaps in a game you have a start menu, some settings, game play, save screen etc. This could for example be done with the state machine pattern instead of a bunch of nestled if-statements. But every body should know that this could be done in many other ordered and 'clean' ways that are not formal design patterns

  • @DavidSpry
    @DavidSpry2 жыл бұрын

    I suspect he's using Clang-Tidy, which is fussy about the use of `explicit` for single-parameter constructors.

  • @bloodgain

    @bloodgain

    2 жыл бұрын

    It's fussy about it because it's a widely-accepted best practice. Linters and other analysis tools should default to best practices, and if you decide to go against them, put the onus on you to disable that check.

  • @DavidSpry

    @DavidSpry

    2 жыл бұрын

    @@bloodgain Indeed, I agree.

  • @rmt3589
    @rmt35897 ай бұрын

    That's so exciting! Just started planning out my own Game Engine, and you're one of my recently found inspirations! Been watching a lot of your videos sense. To know that I can send it in for you to review, that's super exciting!!! Deffinately have my heart set on that now! Btw, you should totally make your own minecraft clone! Would love to see one done with hazel!!!

  • @beastle9end499
    @beastle9end4992 жыл бұрын

    I actually do this with the explicit too if the constructor only has one parameter, because I think it's a better design to have everything explicit by default. This is exactly how you actually make every reference const at first, unless you already know you want to mutate it.

  • @pantsoff

    @pantsoff

    2 жыл бұрын

    Yeah, this is very common. I'm not sure why such a big deal was made about this, especially right after he went over how he likes APIs to be clear

  • @bloodgain

    @bloodgain

    2 жыл бұрын

    Both are considered best practices. Keep doing them!

  • @IONATVS
    @IONATVS Жыл бұрын

    I believe Minecraft Bedrock Edition (ie the modern version of Minecraft Pocket Edition, which is available on Mobile, Consoles, and Windows PCs) has a C++ codebase, as opposed to Java Edition (the Original, available on Windows, Mac, and Linux)’s use of Java (obviously, it’s in the modern name). Maybe it was C#, but in any case, Bedrock is already an entire rewrite of Minecraft in an entirely different language.

  • @Originalimoc

    @Originalimoc

    4 ай бұрын

    Yes, but most importantly its block algorithm is much more efficient resulting HUGE fps speed up. Not (mainly) because used C++.

  • @ale-lp
    @ale-lp Жыл бұрын

    There are so many cool things you could expand the Code Review series into... General review, optimization, architecture. I'd watch them all even if it's an hour long video per project per sub-series!

  • @bluustreak6578
    @bluustreak65782 жыл бұрын

    The thing that impresses me the most is how he's able to understand what the code does so fast

  • @joelincz8314
    @joelincz83142 жыл бұрын

    It's inspiring to see what people are creating at the same time super insightful to hear an experienced person comment on it. Thank you to both!

  • @samarthtandale9121
    @samarthtandale9121 Жыл бұрын

    Love this review 🤩 learnt a lot !!! Huge fan cherno, wish I'll meet you some day!

  • @DeathAtYourDoorStep
    @DeathAtYourDoorStep2 жыл бұрын

    Love the code review videos Cherno!! Keep them up thank you

  • @kariakichernocherno2274
    @kariakichernocherno22742 жыл бұрын

    Hi cherno this is a great podcast love you man!

  • @ShinQdan
    @ShinQdan2 жыл бұрын

    24:20 It's funny the actual Minecraft is written this way in Java as far as I remember - loads of passing the World object down to entities

  • @kech-agmaio8620
    @kech-agmaio86202 жыл бұрын

    love the chill background music

  • @Erock634
    @Erock6342 жыл бұрын

    Really good advice! I love your coding style

  • @TechEreb
    @TechEreb2 жыл бұрын

    I really like this kind of video. It helps me learn better coding practices.

  • @monetlarry8400
    @monetlarry84002 жыл бұрын

    Thanks, Cherno! I learned a lot from this episode!!

  • @propov1802
    @propov1802 Жыл бұрын

    16:16 C++ CoreGuidelines. "C.46: By default, declare single-argument constructors explicit Reason To avoid unintended conversions."

  • @neijiagongfu

    @neijiagongfu

    Жыл бұрын

    👆thats a good reason, not just a matter of taste.

  • @teamcreative8302
    @teamcreative83022 жыл бұрын

    I was waiting for this to happen!

  • @victornpb
    @victornpb2 жыл бұрын

    while I agree with most of the criticisms, I find that a lot in this video comes down to personal preference, and the author didn't do anything that is specifically bad. I think it's important to separate what are "do's and don’ts" from "there's this other way some people prefer", this discrimination is something very important I learned in code review etiquette.

  • @prezadent1

    @prezadent1

    2 жыл бұрын

    *distinction

  • @csisyadam

    @csisyadam

    2 жыл бұрын

    I had the same feelings while watching this video. In a real world environment, colleagues wouldn't like Cherno's "blaming" :)

  • @victornpb

    @victornpb

    2 жыл бұрын

    @@prezadent1 define discrimination: The ability or power to see or make fine distinctions; discernment.

  • @prezadent1

    @prezadent1

    2 жыл бұрын

    @@victornpb So now you know. You're welcome.

  • @victornpb

    @victornpb

    2 жыл бұрын

    @@prezadent1 I don’t think you understand. they mean the same thing.

  • @ruddymolina7044
    @ruddymolina70442 жыл бұрын

    Master you have provide us with new knowledge... thanks master.

  • @sarahkatherine8458
    @sarahkatherine84582 жыл бұрын

    30:46 I'm sorry if this is not Isti's case. This "MovementDirection" trick seems to be used by a lot of previous-generation teacher and programmer (or at least in my country). The idea is, instead of writing x += 0; y += 1; to move upward, they will create a "movement direction array" like this: dirX = {0, -1, 0, 1, -1, 0, 1, -1, 0, 1}; dirY = {0, -1, -1, -1, 0, 0, 0, 1, 1, 1}; Now to move upward, they will do x += dirX[8]; y += dirY[8]; because Num8 is up on your numpad (you are at Num5). They said it will saves a lot of if-else for all 8 directions, and makes it easier to tract the direction by looking at the numpad and array index.

  • @AntonioNoack

    @AntonioNoack

    2 жыл бұрын

    Nice trick, but has nothing to do with the code in this video 😅. Lsti just defined what direction has which xyz coordinates without any tricks, and stored whether the key is pressed in there additionally.

  • @sarahkatherine8458

    @sarahkatherine8458

    2 жыл бұрын

    Yes, Isti's code is not any trick, just pre-defined direction vectors as Cherno said. I just borrowed the name because it reminds me of the mentioned trick 😅

  • @zxuiji
    @zxuiji2 жыл бұрын

    16:07, another reason to put public stuff 1st is to reduce ABI issues when you change something in the private section, if the public stuff is 1st then it will remain in the same ABI spot so long as nothing changes in the public section (or what it inherits from)

  • @alexanderdonets5321

    @alexanderdonets5321

    2 жыл бұрын

    Glad you mentioned that, now I know the name of the general concept (ABI). Recently I've faced only with "binary compatibility" of assemblies in C#, but had a hunch that this is not a language-specific problem. P. S. hadn't got formal education in CS, guess that's why I'm learning this in a weird way :D

  • @zxuiji

    @zxuiji

    2 жыл бұрын

    @@alexanderdonets5321 Good to he- er, read, for reference the 2 common terms I'm familiar with for any language is: 1. API, while I'm sure you know what this term means I'll clarify for those who are not, Application Programming Interface, all the functions, variables and constants that can access of a given library &/or system. 2. ABI, Application Binary Interface, what an API compiles down to for the computer to understand instead of humans, even the slightest mis-match can cause the computer to not understand where it should look for a given call, variable &/or constant when it is referenced in the compiled down code

  • @davidm2.johnston684
    @davidm2.johnston684 Жыл бұрын

    This is the video that has spent the longest time in my "Watch Later" list. Years. Not that I don't clean it regularly, or that it's a place where videos go to die. But this video has survived there for all this time. And I finally watched it today. I needed to be ready. Ready to dive again into C++. And so yeah, good video! It made me want to try something like this too!

  • @davidm2.johnston684

    @davidm2.johnston684

    Жыл бұрын

    All jokes aside, I'm a Python programmer, have been doing that professionally for 3 years, in the animation industry. I've watched a lot of courses on C++, including yours, which made me familiar with the thought patterns, and the specific concepts and culture of the language. And of course the syntaxe. But every time I tried to start a project, I got stuck with other stuff. With configuring my project and my tooling. I guess I'm trying too hard to have the perfect setup, with an IDE that is well configured, the right build and build automation tools, etc, etc. And I can never understand all that or get everything to work. Same if I try to clone an existing project and build it. I've managed to do that for Blender and for Minecraft (with a modding API), but that's because everything has been perfectly automated for every single platform. With other projects, at the tiniest hiccup, I get stuck for whole days. Also working on Windows may not have been the best idea, as many projects are actually configured for Linux. Yeah, that's why I was putting that off for so long. But I will give it another go sometime. I'd like to write a ray tracer sometime, and I've saved your Ray Tracing series for when I'd get the courage again.

  • @randyprime
    @randyprime2 жыл бұрын

    that studio lighting is SEXY AF

  • @austinschaap8739

    @austinschaap8739

    Жыл бұрын

    Thank you Randy (love you btw, come back soon but only if you feel like it)

  • @ronin2963
    @ronin29632 жыл бұрын

    It's really Kool that you are doing this. It is one of the most positive aspects of the coding community

  • @charlestheanimator1676
    @charlestheanimator16762 жыл бұрын

    15:40 I would agree with you to that point about class labels for private and public. That said I have pretty intimate knowledge of the Unreal Engine and their code is riddled with header files that have multiple private, public and protected sections. Upwards of sometimes 3 of each per class. AND, every single class has private data members in the top 'default' private section (of which is not labelled private).

  • @amayesingnathan

    @amayesingnathan

    2 жыл бұрын

    I like to have multiple private, public, protected for members and methods and operators. This gives a clearer boundary between functionality and state in the class. It only ever really ends up applying to private/protected because I almost never have public data members.

  • @DemetryRomanowski
    @DemetryRomanowski2 жыл бұрын

    I use CLion with CLangTidy and the explicit comes directly from that, I changed mine to not constantly pester me to make constructors explicit.

  • @makotomiyamoto5249

    @makotomiyamoto5249

    2 жыл бұрын

    This is actually the same reason I use explicit constructors. As a general rule of thumb I will declare a one-argument constructor implicit just so CLang-Tidy doesn't yell at me, but I can also see how it would be good for consistency with other one-argument constructors that may benefit from it.

  • @bloodgain

    @bloodgain

    2 жыл бұрын

    CLion and ClangTidy are correct. Cherno is wrong. Making single-argument constructors explicit is considered a best practice. You _don't_ want implicit conversion in most cases, and it can cost you performance even if it's not introducing errors.

  • @makotomiyamoto5249

    @makotomiyamoto5249

    2 жыл бұрын

    @@bloodgain Does implicit conversion occur even when your type matches the type the constructor accepts? I must admit that I am not as familiar with C++ under the hood as I should be. Thanks for the insight

  • @bloodgain

    @bloodgain

    2 жыл бұрын

    @@makotomiyamoto5249 In most cases, yes. Like all things in C++, the answer is "it depends" or "it's complicated". But if the compiler can determine a resolution for a call ("substitution"), in nearly all cases, it will insert that resolution unless it has been instructed not to, like with "explicit". Unfortunately, the way C++ determines substitution/resolution can lead to some weird corner cases and doesn't allow neat tricks like multiple dispatch, but it's also what makes some other neat tricks work, like complex template resolution (see: SFINAE).

  • @makotomiyamoto5249

    @makotomiyamoto5249

    2 жыл бұрын

    @@bloodgain Ah I see what you mean. It's good to *explicitly* (pun definitely intended) declare the constructor explicit since whether the resolution will actually take place when types match is not guaranteed by the standard (implementation-defined), only that "explicit" makes it so that it doesn't. Do I have that right? I also never considered how this is related to SFINAE. There's clearly still a lot I don't know! Thanks again for your input

  • @vaanidel2117
    @vaanidel21172 жыл бұрын

    30:54 A camera tutorial would actually be really nice 😅

  • @MaddGameMaker
    @MaddGameMaker8 ай бұрын

    Application::instance() does not do any lazy loading. In C++, all static variables (including local ones) get initialized before main() is called.

  • @cummins6945

    @cummins6945

    27 күн бұрын

    The C++ standards disagrees with you here (see [stmt.dcl]), but tbf you might have been thinking of C. However C doesn't do any dynamic initialization for statics and it's compile time only. Another detail is that the C++ initialization-on-enter is required to be thread-safe: "If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization." This means the compiler has to insert synchronization there when needed

  • @NewPlayer4U
    @NewPlayer4U Жыл бұрын

    TheCherno! I remember your C++ series with these awesome memory checks! Smart Pointers was just BLAST! Where are those razors? ;] How are you even doing Cherno? Do you live well? Everything alright? Maaan, I wish we can drink vodka someday together ;] Thanks a lot for your time, I really appreciate it! You're the best!

  • @aaron6807
    @aaron68072 жыл бұрын

    I started learning OpenGl and C++ by making a minecraft clone too. It's interesting to see how others implemented the same systems

  • @anon1963

    @anon1963

    2 жыл бұрын

    it just works

  • @cxlappsed1548

    @cxlappsed1548

    4 ай бұрын

    link?

  • @Spongman
    @Spongman2 жыл бұрын

    yeah, look at the asm for local static instance. it has a memory barrier around it, which is going to kill multi-threaded performance, especially on something so central.

  • @alfredli4032
    @alfredli40322 жыл бұрын

    Cherno I like this review very much, learnt alot. by the way can you do a hazel version minecraft

  • @Ezdiess
    @Ezdiess2 жыл бұрын

    What a brilliant brilliant plug

  • @user-dh8oi2mk4f

    @user-dh8oi2mk4f

    2 жыл бұрын

    Brilliant 👏

  • @spectrm6014
    @spectrm60142 жыл бұрын

    The series is going good so far :) Early btw 😀🙌 🔥

  • @NordicFrog
    @NordicFrog Жыл бұрын

    18:16 that is a Linus Tech Tips level segway right there. Just perfect.

  • @CodAv123
    @CodAv123 Жыл бұрын

    Regarding the missing header files: I often see people using CMake not adding them to the targets, because technically that's not really required for building and CLion (which the author probably used) will show the directory structure instead of just the target files as VS does. Adding the headers is advisable for multiple reasons though. CMake will use all files added to the target - even non-code files - to determine if a target is out of date, depending on modification dates. So not adding headers might not retrigger a recompile of a target with some generators/build tools. Also adding headers will make them show up in project-based IDEs like VS. In addition to that, one should also set some additional CMake properties to properly sort targets and files into filters/subdirs to make them easier to browse.

  • @student99bg
    @student99bg Жыл бұрын

    At 24:50 Yes, PLEASE! Those kinds of questions of OOP, questions of design, what class should do what is what I want to know so bad. I would like to watch videos on that topic in fact this very discussion about what the Ray and other objects should know about the world and which class should take care of collision detections is something that I am really interested to know. It is also interesting that you can build projects as big as Minecraft clones in OpenGL despite the fact that your design decisions are bad.

  • @LegoDinoMan
    @LegoDinoMan Жыл бұрын

    I’d love for you to turn it into an optimisation series! Teach me the ways of speed

  • @atlantic_love

    @atlantic_love

    Жыл бұрын

    I wouldn't, and that's not what he's about. There are optimization channels you can frequent.

  • @LegoDinoMan

    @LegoDinoMan

    Жыл бұрын

    @@atlantic_love Would you recommended some please?

  • @crusaderanimation6967
    @crusaderanimation69672 жыл бұрын

    1:35 Artists: Artist1: NOOOOO yOu stol My art ! Artist 2: No it's my ART ! ! Programmers: Programer1: I stole your code lol Programer2: This part of code isn't even mine code XD

  • @szirsp
    @szirsp6 ай бұрын

    15:55 I heard a presenter say on some C++ conference that they changed their mind on public first. When I looked into it, I found a good argument against public API first: documentation. Read the documentation if you just want to see how to use it. If you want to see how it works, then you open the code, in which case you want to see the data first. You want to read from top to bottom, and you need to see declarations first and then their usage. So it's not really about public first or private first, it's about fields (member variables) first then methods (member functions). It just happens that in most cases data is private and methods are public.

  • @6aston6ames
    @6aston6ames2 жыл бұрын

    Idk why, but, Ghost Cherno made me have to pay attention to the code D:

  • @zxuiji
    @zxuiji2 жыл бұрын

    as for constructors vs destructors, I like to put the destructors 1st, even in the implementation file, it makes it easier to know what you need to initialise in the various constructors since I would normally just start writing the next constructor directly underneath the destructor so I can quickly reference it, also since the destructor has a shorter api it just looks nicer to go from short api to long api

  • @user-ph5cu2tr8d
    @user-ph5cu2tr8d2 жыл бұрын

    awesome!

  • @stephenkamenar
    @stephenkamenar2 жыл бұрын

    i like the performance reviews. the main point of writing your own engine is performance.

  • @thepurplepanda4

    @thepurplepanda4

    2 жыл бұрын

    Or learning what happens under the hood. I'm not making an engine, but I am making a graphics program. My purpose is purely to learn and show a project for potential work.

  • @m4rt_
    @m4rt_10 ай бұрын

    2:30 Jonathan blow is taking making it from scratch to the extreme. He is working on a game, in a programming language he is making, where it has no separate engine, just the game. Though I think he did copy over C++ code from his earlier games that didn't have a separate engine either.

  • @user-iy7rm7dt8x
    @user-iy7rm7dt8x2 жыл бұрын

    Good. Very good video.

  • @b4ttlemast0r
    @b4ttlemast0r Жыл бұрын

    Can the code review code be in any programming language, even lesser known languages and engines?

  • @tomasofficial.
    @tomasofficial. Жыл бұрын

    Hello, how did you change the color scheme to be like that instead of the default?

  • @lunaerx2017
    @lunaerx20172 жыл бұрын

    Hi Cherno! I want to ask you to make the review of WebGPU technology. I see it has some potential in the future not only for web, but also for desktop because it provides an abstraction over native APIs like Vulkan, Metal and DirectX. Unfortunately, I don't see the full picture of it because of a lack of experience working with graphics in general. So I would really like to hear thoughts and opinion from you as a very experienced graphics software engineer. Hope you'll see this message and eventually make the review! Thank you.

  • @yoyo12345
    @yoyo123452 жыл бұрын

    waiting for java code reviews :)

  • @svens3722

    @svens3722

    2 жыл бұрын

    then he have to do it in a pool that nobody sees him crying.

  • @yoyo12345

    @yoyo12345

    2 жыл бұрын

    @@svens3722 sad, why do people hate java

  • @svens3722

    @svens3722

    2 жыл бұрын

    @@yoyo12345 i started with c and c++. After that i got in school java and i was confused where all come from and i didnt liked it how it worked. but i have to admit that this opinion was kinda of my "beginner noob programmer" thinking builded.i didnt understand it fully. nowadays i think its quite handie and i would like to step into if i have to. but with my private stuff i prefer other languages.

  • @pinguluk1
    @pinguluk12 жыл бұрын

    What's that menu at 7:42? It's a library that you can implement in C++ GUI projects? I've seen it in other C++ projects as well 🤔

  • @master_spike

    @master_spike

    10 ай бұрын

    Imgui

  • @samiam4039
    @samiam40392 жыл бұрын

    Is the game engine a place where you abstract the device driver and direct connect drivers and the graphics pipeline from the real game code. In a way the game engine can be considered the compatibility code and gaming display conversion from the actual game specific code?

  • @atijohn8135

    @atijohn8135

    2 жыл бұрын

    That's a graphics rendering API, like Direct3D or OpenGL. A game requires more elements than just graphics rendering (physics, UI, AI etc.)

  • @DominikGuzowski
    @DominikGuzowski2 жыл бұрын

    Well now we need a HazelCraft 😂

  • @TheRealMangoDev
    @TheRealMangoDev9 ай бұрын

    "Application is such a like important part of your application that like uh like why not you know just kind of create it here" - Cherno 2022

  • @OperationDarkside
    @OperationDarkside2 жыл бұрын

    I'm also doing a Minecraft clone, but it's nearly not as tidy as this guy's code and has a lot less features. I startet like 3 years ago and have less features than he does xD However, mine has more evolved into more of a experiment lab for graphics stuff. Just figuring out how to write a decent blur renderer took months and recently I ported the app to C++ modules, which ate another 2 weekends. And I'm guilty of getting lost in code optimization, despite running at 120 fps at 2% CPU load. GPU has been strange though. when I implemented a way to reduce vertices per chunk and draw calls in general the GPU usage jumped to 50% oO

  • @johnmccain3050
    @johnmccain30502 жыл бұрын

    @The Cherno When you showed your Hazel code how you set up the "Application". Why didn't you use a smart pointer to wrap your "Application" object? you explicitly have to call "delete app".

  • @user-dh8oi2mk4f

    @user-dh8oi2mk4f

    2 жыл бұрын

    It doesn’t make any difference. There’s only one logical place to delete the app.

  • @abhinavjha3082
    @abhinavjha30822 жыл бұрын

    Could someone tell me which theme Cherno is using? I love it

  • @led23zeppelin

    @led23zeppelin

    2 жыл бұрын

    It's a theme you get with a payed VS extension called VisualAssist. You can, however, recreate this theme yourself with a color-picker on the colors you see in the video

  • @abhinavjha3082

    @abhinavjha3082

    2 жыл бұрын

    @@led23zeppelin ooh thanks bro

  • @VioletGiraffe
    @VioletGiraffe2 жыл бұрын

    You're just teasing us with all these videos that are NOT about ray tracing, right? :)

  • @pmcgee003
    @pmcgee003 Жыл бұрын

    Passing state (the world) into a function *is* a functional approach.

  • @adamhelberg9228
    @adamhelberg92282 жыл бұрын

    I have seen over a few videos that you dont like singletons, is there a reason ?, does it make it slower or use more memory?, I'm still learning so knowing might help for future.

  • @AntonioNoack

    @AntonioNoack

    2 жыл бұрын

    Singletons can be bad for modularity, because you can only have one of them. On Android you're additionally told to avoid static references to your main UI class, because the system cannot garbage collect it then, when the classes shall stay in memory (e.g. so the app can restart faster).

  • @bloodgain

    @bloodgain

    2 жыл бұрын

    Basically, it's a global that _forces_ you to only ever have one instance of it. Because it's global, it makes testing harder, because it's an undeclared dependency. Better design would be to declare all dependencies as parameters (either at construction time or use time). This is called Dependency Injection or Inversion of Control. While some things conceptually are globals, actually using global references should be done very sparingly, and avoided whenever possible. But this goes for _all_ globals. But worse, because it _enforces_ a single instance, it takes away the programmer's control over its lifetime. Thus, it has to be created at startup, live after shutdown or a least until static destruction time (leading to the Destruction Order Fiasco problem), or often both. This is a massive drawback that can be solved by simply not having a class control its own creation and destruction time. So, if you do decide to use a global, avoid making it a singleton pattern. You can have a global if you have to, fine. You can have only a single instance, also OK. But don't push those into the design of the type and adopt more downsides than necessary.

  • @nathan8245
    @nathan82452 жыл бұрын

    What's the ide you're using ? Love the way it makes the != and

  • @TheCherno

    @TheCherno

    2 жыл бұрын

    Visual Studio 2022, however this is part of the font I believe (Cascadia Code)

  • @stephenyork7318
    @stephenyork73182 жыл бұрын

    One of the most important things I've learned over the years with OO is to STOP inheriting and making classes do too much. It's so much more manageable to to have data classes which represent a thing (noun) and have the behaviour of that thing represented by other classes, which typically do only one thing and do it well. I don't actually mean never inherit, but the ability to inherit generally leads to problems and it's a fine art to know when you genuinely need to do it. But anyway, dependency injecting (the pattern not and IoC container) following SOLID keeping clases super simple was a revelation to me.

  • @daithi007
    @daithi007 Жыл бұрын

    14:00 Moved the private data members to the bottom of the class implementation. You're complaining about it being first but you're looking at the implementation you're not looking at the header.

  • @spidermankey1398
    @spidermankey13982 жыл бұрын

    please work on ray tracer series

  • @frydac
    @frydac2 жыл бұрын

    wrt the ray depending on the world: this code is highly, pretty sure unnecessarily, coupled to the world class. A ray class is normally something you want unnittests for to make sure it works correctly and it enables you to change/optimize the implementation without worrying about breaking it's functionality. When you write lots of unittests, and you should, then you notice that setting up a world class just to test the ray is quite annoying. If you ever start a new game and need a ray there, this class is also not usable as you probably want a different world (though this ray may be really specific to the minecraft block layout of course). I would strongly recommend trying to write unittests and think about the testability of building blocks like a ray. It will make it relatively easy to make your code less coupled, and thus more maintainable and reusable. This is kind of the idea behind TDD, imho it really works to think about testability all the time when designing, not necessarily writing tests first, though in some cases that works very well too. Same for the singleton, it really undermines testability: you want different testcases to be completely independent, but a singleton keeps existing between testcases so it makes it more error prone as you need to make sure to reset the singletons state between testcases.

  • @anirudhsilverking5761
    @anirudhsilverking5761 Жыл бұрын

    What's the font you're using??

  • @gravenviolet
    @gravenviolet5 ай бұрын

    Thank you for giving me a glimpse of how to make a minecraft bedrock

  • @tumaraigordai4157
    @tumaraigordai4157 Жыл бұрын

    Does anyone know the name of BGM at the start?

  • @quwelrizki2570
    @quwelrizki25702 жыл бұрын

    Wooww, cool man, whos make the code is cool people. Amazing.

  • @nodecrasher4991
    @nodecrasher49912 жыл бұрын

    How many more of these mincraft clones are going to be there

  • @brightwebltd2864
    @brightwebltd28642 жыл бұрын

    Cherno! Check out 4D Minecraft - that’s some crazy game design and math!

  • @Caellyan
    @Caellyan2 жыл бұрын

    vert_lighting (ln 46) of shader code can be optimized a lot with regards to number of instructions generated. min(max(..)) screams "replace me with clamp", and in this case the glsl compiler wouldn't replace it with min(max()) as the upper limit is a variable. Sending less data to shaders is good, but in case of a MC clone this might be unnecessary as the world doesn't change that often - so computing positions every frame in a shader is increasing amount of work that needs to be done per frame. This depends though on how much work you need your shaders to do I guess.

  • @maximgolubtsov440
    @maximgolubtsov4402 жыл бұрын

    Hi Cherno! Haven't you tried CLion for C++ development?

  • @HazStepFTW
    @HazStepFTW2 жыл бұрын

    Minecraft Clone series coming soon? :D

  • @Loan--Wolf
    @Loan--Wolf2 жыл бұрын

    i have a friend made a game from scratch ever time he was about to get the engion lined out shit upgraded so he was allways haveing to start over

  • @kurciqs8355
    @kurciqs83552 жыл бұрын

    pls cherno minecraft clone!

  • @thelowendstudio
    @thelowendstudio2 жыл бұрын

    Alternate title: Minecraft C++ mining

  • @jcx5750
    @jcx57502 жыл бұрын

    "I can do Unreal Engine 5 lumen tech in three months if I was free of work" -Does a code review of minecraft in c++

  • @Throckmorpheus
    @Throckmorpheus Жыл бұрын

    From modding Minecraft, I'm pretty sure the thing of passing World into functions that feel like they should belong to World is being copied from the way actual Minecraft structures itself.

  • @DemsW
    @DemsW2 жыл бұрын

    If you ever find the will to make a minecraft clone I would love to follow that, and I don't think it would take you much time tbh.

  • @mobslicer1529
    @mobslicer15292 жыл бұрын

    In CMake, you have to explicitly include the header files in the targets

  • @Tachi107

    @Tachi107

    2 жыл бұрын

    Or, even better, you can use target_sources(FILE_SET)

  • @lukesanford9026
    @lukesanford90262 жыл бұрын

    I want to learn how to make games and programs from scratch, though I have no idea where to start. I have very minimal knowledge of the basics of programming and CS, I've worked in Java, Python, C++, and C#, though never beyond the point of basic baby stuff like...creating and calling functions. I don't even know what header files are or what any of those lines of code mean and while I don't want it to intimidate me, it does. Anyone have any advice on where to begin?

  • @Starchaser38

    @Starchaser38

    2 жыл бұрын

    Header file is just a chunk of code, which can be embedded into another file by specifying #include "filename.h" directive. They are generally used when some specific code is widely reusable in many different projects or represents a completely different functionality (so a bunch of barely connected stuff won't make an unreadable mess in your main file). In basic stuff you probably didn't have a need for any of these (except for perhaps), but the concept is really simple and straightforward. As for beginning of programming... Well, if you're interested in understanding the syntax of C++ and it's basic functionality, there are some specialized books on the topic, like Straustrup's ones (he's the creator of this language after all). Also the internet is full of beginner level tutorials. In general though, I would recommend to set some pretty high goal for yourself (like creating a game, a useful app, a simple engine...) and to do your best to progress towards it. Even the path itself would be a great teacher.

  • @Wilksey37
    @Wilksey372 жыл бұрын

    If you want a code review challenge, review the BUILD engine (Duke Nukem 3D) code....

  • @AntonioNoack

    @AntonioNoack

    2 жыл бұрын

    Oh well, then he could review Unreal Engine, Blender or Godot as well, but that's waaaayyyy too much. or my engine, but that's still 100k lines 😅

  • @Wilksey37

    @Wilksey37

    2 жыл бұрын

    @@AntonioNoack BUILD engine is notoriously bad and convoluted though...If you want him to review you engine then send it to him.

  • @szirsp
    @szirsp6 ай бұрын

    26:10 I think that Ray utility class might just needs a rename (something like WorldBlockColliderRay), or maybe moved into the World class. I mostly agree with Cherno here but I kinda disagree that the player and ray necessarily exist within the world. Minecraft has multiple dimensions/worlds. The ray belongs to the player. It can exist outside of a world (if you want to have a character creation/customization menu/screen... but then you wouldn't need the ray), or it can exist in multiple worlds simultaneously: like stepping or looking trough a nether portal or end portal (if you wanted to make them see-through, I saw a mod for that in MC). But you can achieve these as if the player existed in a void world or in multiple worlds all at once, call the world's ray collider function on multiple worlds. You could pass a collider object to the Ray and implement the world's collider, but the result is probably the same, that world specific code doesn't belong to a generic Ray class. You probably should ask the world for ray collision result, rather then a generic looking ray dig into the world internal structure. (The indirection makes this slightly less efficient, but you can still use this in the constructor.) I get why the work is done in the constructor, it's more efficient, the results take less space to store than the inputs, and called less frequently. I don't know if the world is holding only block data, but at some point you might want to implement entities (mobs, maybe chests), then ray collisions with those might be separate from world, and that might be a reason why not to implement this in the World class. Still Ray probably should receive a list of colliders (world's, entity's) and call those.

  • @YouTubeName-hw1uk
    @YouTubeName-hw1uk2 ай бұрын

    The best Minecraft clone is any conceal addition

  • @proletar-ian
    @proletar-ian11 ай бұрын

    Love to see someone bagging on UML diagrams and getting to ideological about programming paradigms lol

  • @awwastor
    @awwastor2 жыл бұрын

    25:00 You can just do cast_ray(Ray, World, ..context) to be completely neutral

  • @feschber

    @feschber

    2 жыл бұрын

    But then this function would need knowledge about World, which only World itself should have. So imo having a World::intersect(Ray &ray) function is still the best approach (and our professor did it this way in a university assigment as well)

  • @awwastor

    @awwastor

    2 жыл бұрын

    @@feschber why should only World have access to itself, but Ray not?

  • @feschber

    @feschber

    2 жыл бұрын

    @@awwastor its not about access, but why should Ray need to know anything about world? That just complicates things. Ray doesn't _need_ to know anything about the world.

  • @jan-lukas

    @jan-lukas

    2 жыл бұрын

    ​@@feschber my rule of thumb is: when two (or more) headers include each other, I've made a mistake and should move some things around

  • @danieloberhoff1
    @danieloberhoff12 жыл бұрын

    I disagree with the explicit constructor criticism. You can accidentally create an instance, even if the function has const& args. especially if the coinstructor takes only string.

  • @TheCherno

    @TheCherno

    2 жыл бұрын

    You can’t really accidentally create a class from a string, since that would take two conversions (const char* to std::string to class). In my experience, in most cases where a conversion is possible (for most types, not all), the conversion is the intended behaviour

  • @soheibmemes2594
    @soheibmemes25942 жыл бұрын

    cool

  • @BartKus
    @BartKus2 жыл бұрын

    16:16 explicit single-argument constructors are suggested by Google's style guide. "google-explicit-constructor" clang-tidy check can enforce this.