Space Invaders Clone in C# // Code Review

Поделиться
HTML-код
  • Опубликовано: 28 окт 2024

Комментарии • 213

  • @TheCherno
    @TheCherno  2 года назад +59

    What did you all think of this _feature length_ Code Review episode? More of these or shorter? Also you all should definitely check out Brilliant if you haven't already, it's honestly a great website. Visit brilliant.org/TheCherno to get started learning STEM for free, and the first 200 people will get 20% off their annual premium subscription.

    • @alexkhazov7264
      @alexkhazov7264 2 года назад +7

      I love the longer versions! It's like a fun and casual educational chat and you're able to look at more things and/or go into certain parts in more depth, which is always more beneficial

    • @M3lodicDeathmetal
      @M3lodicDeathmetal 2 года назад +2

      I like the length and I like the new format with Tim. Bobb on!

    • @Flashfake
      @Flashfake 2 года назад +4

      The fact that there is dialogue in both directions, the longer format was enjoyable. It also externalises the thought processes, allowing to relate easier.
      Also Bobb.

    • @ultramarinebicycle
      @ultramarinebicycle 2 года назад +1

      I voted no on the "should code reviews be longer than an hour" poll, but this was awesome. As a self taught game programmer, I am learning a lot from this video!

    • @johanrojassoderman5590
      @johanrojassoderman5590 2 года назад

      Absolutely longer. You can get in a lot more details and nuances in them that would expand our knowledge more than five shorter videos lacking that in-depth analysis. However, the raw OpenGL/c++ videos are probably more up my alley. It's quite interesting to see other people's solutions and mistakes on that level.

  • @Arcadenut1
    @Arcadenut1 2 года назад +58

    The first rule of Optimization is only optimize what needs to be optimized. The for loop of 6 items in the initialization has such an insignificant impact on performance that you wouldn't spend any time optimizing it. Read-ability in this case is more important than speed. Branching is also minor compared to memory allocation and other code that might be optimized away.

    • @hbgl8889
      @hbgl8889 Год назад +1

      True. And another rule is to measure the thing you are trying to optimize.

    • @carltonkess862
      @carltonkess862 5 месяцев назад

      makes sense, but i did appreciate the new perspective, and this one.

  • @alexkhazov7264
    @alexkhazov7264 2 года назад +17

    The correct spelling is Bob. The double b in cases like Bobbing or Bobbed is because of the CVC rule in English grammar - when adding a suffix to a one-syllable word, and the last 3 letters are a consonant-vowel-consonant, then you double the last consonant. For example: Swim -> Swimming, swimmers, but you wouldn't be writing:
    enum class PlayerActions
    {
    Swimm
    };

    • @NNOTM
      @NNOTM 2 года назад

      not if it's a single swim, but what if it's multiple swimms

    • @JorgetePanete
      @JorgetePanete 2 года назад +1

      @@NNOTM of course it's swims

    • @RandomGuyyy
      @RandomGuyyy 2 года назад +3

      Oh mighty mangos! Why stand when you can... SITT

    • @chiyungchu9463
      @chiyungchu9463 2 года назад

      so it should be rememberring or remembering? Am i understanding correctly, "ber" seems fit the CVC rule.

    • @Robbatog1
      @Robbatog1 2 года назад

      @@chiyungchu9463 remember is not a one-syllable word though.

  • @arlasoft
    @arlasoft 2 года назад +83

    The original Space Invaders moves one invader per frame. Therefore the speed increase happens naturally, as more aliens are destroyed there are less to get through before looping around again.

    • @AdroSlice
      @AdroSlice 2 года назад +10

      That's actually pretty smart, I like that.

    • @quintongordon6024
      @quintongordon6024 2 года назад +5

      @@AdroSlice Pretty elegant design

    • @wjrasmussen666
      @wjrasmussen666 2 года назад +1

      You are right. I thought this was common knowledge?

    • @josephmellor7641
      @josephmellor7641 2 года назад +6

      @@quintongordon6024 I thought it was originally a bug that became a feature. The game was intended to move more quickly but the hardware couldn't handle it.

    • @nomit6033
      @nomit6033 2 года назад +1

      Pretty smart! You can look on James Sharmans Channel. Hes building an discrete CPU and shows some programming technics from the old days. There was a lot of designs like the moving per frame thing

  • @ufookoro1
    @ufookoro1 2 года назад +41

    This was totally brilliant.
    It did not seem in any way scripted.
    There was genuine critique going on which was awesome.
    I learnt a lot with regards to the if’s and else nesting.
    I don’t program in C#, but in Python, the same can happen.
    Looking forward to the next iteration of this code review.
    Thanks 🙏

  • @sunfire5518
    @sunfire5518 2 года назад +8

    This has to be my favorite of the code review yet. As an relativ beginner, i really enjoy the mentoring style you have, while explaining to Tim. The constant C# / C++ comparisons really help grasping the similarites in designing things as someone who has mostly coded in Java in uni. I would love to see Tim more :)

  • @bukinnear
    @bukinnear 2 года назад +21

    "If anyone needs a job, who spells 'bob' normally... We've just had an opening."
    FINALLY, A JOB DESCRIPTION I AM FULLY QUALIFIED FOR!

    • @onejdc
      @onejdc 2 года назад

      Plus Senior Level Developer with 25 years of experience in GO, and 3 years in SAP.

  • @AndrewHelgeCox
    @AndrewHelgeCox 2 года назад +25

    25:00 I think it would have been good to emphasize two main reasons that this for loop transformation doesn't matter.
    The first, which IIRC you didn't talk about, is that it has six iterations, not thousands or millions, and is executed once at startup, not during the game update loop. These facts make this loop a low priority for any performance improvement, not just the one mentioned.
    The second, which you did cover but with some equivocation, is that any compiler in recent decades can easily hoist the branch out of the loop and perform exactly the code transformation that you suggested doing manually. The rewrite is thus about aligning the code as written in text for the programmer's eye with how it should run, not with producing better machine code.

    • @user-sl6gn1ss8p
      @user-sl6gn1ss8p 2 года назад +2

      I think it would probably not really matter either way because of how absolutely predictable it is. Between the compiler and the branch predictor, you shouldn't really be that penalized.
      I'd still separate it tho, and it sure is important to keep in mind the size (and frequency) of the loop : p

  • @DeGuerre
    @DeGuerre 2 года назад +22

    16:10 A little-known fact in managed languages is that reading from and writing to a stack variable is faster than reading from or writing to an object member. Now you probably won't even be able to measure the difference in this case, because it's only 6 times and it's only on initialisation, but this is important to know about in performance-sensitive applications.
    Languages like Java and C# have a concurrent garbage collector, which runs in a thread while your program is running, to minimise pauses. Storing into a member variable is mutating the heap, and the if you're doing that while the garbage collector is active, it may need to know that the mutation occurred. The details are complicated, but the mechanism used for this is called a "barrier". Some garbage collectors use read barriers, and others use write barriers; write barriers are more popular because writes to the heap are less common than reads.
    A barrier is not very much code, maybe a few cycles, but it still needs to happen on every heap read or write. Reads and writes to stack variables do not need this because a thread's stack cannot be mutated concurrently by other threads. Stack operations may still involve some cooperation with the GC, but typically only at designated checkpoints.

    • @Muertpe1884
      @Muertpe1884 2 года назад

      Nice to know, do you have some sources for further investigation?

    • @pxolqopt3597
      @pxolqopt3597 2 года назад +3

      I feel like if you are writing code where something like this is the difference between being acceptable or not you should be using a language like C/C++ or Rust

    • @DeGuerre
      @DeGuerre 2 года назад +3

      @@pxolqopt3597 The reason why I brought it up is the same reason that Cherno brought it up.
      I've been programming for almost 40 years, and every so often I find a good habit, and cultivate it. Given a choice between using a stack variable as a temporary vs using a member, it's a good habit to use a stack variable.
      It won't make a difference most of the time, but that one time when it will make a difference (e.g. in a loop over a million things), you'll automatically do the right thing.
      The point isn't that you should think about scrounging a few cycles in initialisation code. The point is that it's just as easy to do either here, so you should be in the habit of doing the better one by default, so you won't HAVE to think about scrounging cycles when it matters.

    • @DeGuerre
      @DeGuerre 2 года назад +1

      @@Muertpe1884 I would ask your favourite search engine for the classic survey "Uniprocessor Garbage Collection Techniques" by Paul Wilson. It's a bit out of date, and it's clearly about single-processor systems, but it gives good examples of what a barrier is and what it's for.

    • @onejdc
      @onejdc 2 года назад +1

      I was looking for this comment. Thank you; beautifully explained.

  • @Dustyy01
    @Dustyy01 2 года назад +11

    35:00 When you add the struct to a field in a class it gets allocated on the heap. If u want to only allocate structs on the stack, you can use ref struct so the compiler doesnt allow u to use it in a Spot where it would get allocated on the heap

  • @dune2themaker
    @dune2themaker 2 года назад +6

    21:57 -> conceptually there are two things at once happening. One is filtering, and one is applying some logic. Doing it in one loop is ok with 1 branch. But if you get more if's inside the loop, it might be easier to understand to filter the list into separate 'lists' and apply one operation on those. Although, in this case there is literally an if-statement to filter out the 'first' element and set a different kind of emission. Suppose you would want to do something more complex and on more letters, then having a 'filter' and 'apply logic' branch separately can make things a bit easier.

  • @maverikmiller6746
    @maverikmiller6746 2 года назад +2

    This was pretty good. Please do more videos like this Cherno.

  • @leddoo
    @leddoo 2 года назад +1

    20:50 `loop { if i == 0 { foo } else { bar } }`
    1) branches are only expensive if they're unpredictable. or in very tight and very busy loops.
    2) don't forget compiler optimizations.
    this pattern (first iteration vs others) is quite common. eg: find max element in a list, where you can't choose a reasonable minimum element.
    using the conditional, you can prevent needless code duplication. a good compiler should be able to unroll the first iteration, removing the conditional.
    edit: sorry, commented too quickly. i see, you mentioned the compiler optimization thing.

  • @garageman2236
    @garageman2236 2 года назад +3

    The hazel look is just intense bloom

  • @Pinky0579
    @Pinky0579 2 года назад +4

    Cherno, you are like a loving father reviewing this code. You are clearly a programmer artist.

  • @atrumluminarium
    @atrumluminarium 2 года назад +13

    Tim is a really cool guy I won't mind seeing him more often on the channel tbh

  • @Mitch_Crane
    @Mitch_Crane 2 года назад +3

    You could write that loop without branching with something like:
    var emission = 0.75
    for each letter
    {
    letter.Emission = emission
    emission = 2.0
    }
    Need to make an additional variable here which I don't know is better or worse. Also might not be immediately obvious when reading. Have not had to do such extreme optimisations on a for loop like this before

    • @pxolqopt3597
      @pxolqopt3597 2 года назад

      I feel like the C# compiler would be smart enough to optimize away the if-else branch into either a conditional move (no branches) or just unroll the loop

  • @calmchess0434
    @calmchess0434 2 года назад +1

    I like specifying the for loop with "if(i==0){}" because if I come back in the future its much clearer what's happening in that for loop.

  • @QIZI94
    @QIZI94 2 года назад +2

    Love this content with real human interaction while reviewing

  • @M3lodicDeathmetal
    @M3lodicDeathmetal 2 года назад

    This video had impeccable timing. I'm writing a parser today and I immediately remember the section about state machines. Before my parser would look cluttered like Tims nested if's, where it was difficult to follow. Now it looks super clean! :)

  • @hanzofactory
    @hanzofactory 2 года назад +6

    You mentioning premake was such a godsend. I always struggled with building c++ code and I just tried it, it is super easy to get started with and works right off the bat! Thanks so much!

  • @mranthonymills
    @mranthonymills 2 года назад +1

    On the subject of loops and unrolling loops: keep in mind that the compiled code for a loop is probably smaller in memory than six repetitions of the loop body, which means the code will fit into CPU instruction caches better. In modern CPUs, because memory accesses are so slow compared to cache accesses, small code sizes are a very valid optimization goal. And also, the code as is may be easier to modify for later revisions where a designer might decide they'd like a different pattern.

  • @thegnosticatheist
    @thegnosticatheist 2 года назад

    This was the best podcast-like video I had in my background for a very long time :)

  • @onejdc
    @onejdc 2 года назад +1

    BOB. One B. I'll submit my application. Good luck in your new endeavors, Tim.

  • @maybenat
    @maybenat 2 года назад +1

    25:00 It's also worth noting that through a single assign I wouldn't be surprised if the generated code only had a conditional move (cmov) instruction generated for it, instead of a branch for `if (i == 0)`

  • @AntonioNoack
    @AntonioNoack 2 года назад

    @24:04 yeah, from a high performance computing standpoint, branches can be very expensive.
    a) if you have vectorized code, each branch needs to execute sequentially instead of in parallel. This applies to GPUs as well (since they are pretty much just vector processors).
    b) if your branch predictor guesses wrong, e.g. because your conditions are random/stochastic, the pipeline needs to be cleared. The pipeline on modern processors is about 10-25 instructions long. This means that a single, incorrect branch predict may cost you 10-25 cycles.

  • @ariseyhun2085
    @ariseyhun2085 2 года назад +40

    Have you just rented an office space? It's looking really legit

    • @lionkor98
      @lionkor98 2 года назад

      probably airbnb

    • @AlexFord-gp7by
      @AlexFord-gp7by 2 года назад +3

      It's either green screen or a very good camera

    • @JustARegularPlayer
      @JustARegularPlayer 2 года назад +2

      I remember him saying that he rented an office space in 2019, but COVID-19 happened, so he's kinda stuck at home for about 2 years.

    • @ariseyhun2085
      @ariseyhun2085 2 года назад

      @@JustARegularPlayer ohh right, he should let us know the situation. I wonder if its just him and Tim. I remember another guy a few months ago in the background

    • @siddhantkhare2775
      @siddhantkhare2775 2 года назад +4

      @@AlexFord-gp7by I Don't think that's a green screen.....

  • @glace848
    @glace848 2 года назад +3

    hey man just wanted to quickly pop in and say thank you for your c++ series. helped me get an A in my exam

  • @dragonboyjazz
    @dragonboyjazz 2 года назад +1

    "does it have to be 'i++' ", actually i think it can be "++i" and it does the same thing because "increment then assign" or "assign then increment" both give the same answer, i might be misremembering though.
    the answer to the bob/bobb question is
    Robert.

  • @matheus-kirchesch
    @matheus-kirchesch 2 года назад +6

    57:00 you should be able to get the position.Y and limit it

  • @andreagrumpeenlate5813
    @andreagrumpeenlate5813 2 года назад +1

    I can’t program in C# and yet this was so informative! Thank you!

  • @1u8taheb6
    @1u8taheb6 2 года назад +1

    You cannot step into Chernu's office with grand ideas about pluralisation. Tim got absolutely deallocated.

  • @logank.70
    @logank.70 Год назад +1

    Cherno: "Think about whether this function could return null"
    C# Developers: "That's why we have nullable reference types now so you can express that your method could return null 🙂"
    Honestly one of my favorite newer language features. I can express my intent clearly and the compiler is really good about catching me being unsafe with my references. Every new project that feature is enabled and turned into a compiler error.

  • @ChrisBNisbet
    @ChrisBNisbet 2 года назад +2

    I'd be dying to move that for loop that sets up the arcade letters into a separate function - and give those emission constants a name.

  • @NKCSS
    @NKCSS 2 года назад +10

    12:15 The null check makes sense, but I'd use it to throw a meaningfull error to describe what would have gone wrong for this state to happen to make sure it's easier to troubleshoot if/when it ever occurs. Being aware of stuff that could go wrong, if you can't handle it, make sure to use it to throw a meaningfull error to help your future self.
    Secondary, try to make it a habit to specify things only once. I know there isn't a way to expose component names, etc easily from Unity, but that doesn't prevent you from having a set of constants with these names somewhere for your reference. This prevents you from making typos on one of the places where you need it, it also gives you 1 single thing to rename when your Designer changes and a 'find all references' target to see where it's in use.

    • @hanzofactory
      @hanzofactory 2 года назад +1

      Yeah, when it's in a virtual machine, I think it's even better to let it throw out an error than not mentioning anything, that way you at least know immediately where things went wrong

    • @TanninZero
      @TanninZero 2 года назад +1

      @@hanzofactory I'd argue that's always the case, even if it's native code. It's better to crash than to ignore an error and continue, who knows what kind of follow-up errors might happen? Sure, it's just a game, but what if a developer who's gotten into the habit of suppressing errors writes a login-form next? In my experience, crashes get fixed fairly quickly because they're easy to narrow down. Code that continues to run with invalid data isn't.

    • @mechslayer5429
      @mechslayer5429 2 года назад

      @@TanninZero When you throw an exception in a managed language, if not handled anywhere the program will crash.

    • @sebastiangudino9377
      @sebastiangudino9377 2 года назад +1

      Dude, but the idea is that you catch and handle the Null so that you DONT throw the exception. Like, you would want the entire game to crash just because one of the models you imported simply happened to take a few ms too long, or a request to a server didn't get back on time. That's what cherno was saying. Sometimes you DO want your program to crash when something goes wrong. But in a game most of the time you don't
      If you have ever programed on JavaScript you know that you can't just destroy the process just because you got an error. Error WILL happen when you are talking with a server, reading and writing to a database, making request to APIs and rendering a bunch of stuff every frame while the user interacts with the website, you have to focus on "hide" and try to handle the error yourself without hurting the user experience. And with games it exactly the game. Nobody will care about a very explicit and descriptive error report if your game is not fun to play

    • @TanninZero
      @TanninZero 2 года назад

      @@sebastiangudino9377 What are you talking about? The error in the video wasn't about "the models taking a few ms too long", it was about required objects not being assigned in the editor. If there was an exception there, the game has a bug.
      And the solution proposed in the video wasn't to handle the error in any reasonable way but to suppress the exception which would have led to another object not being assigned which would probably have led to another exception further down the line - just more obfuscated.
      I'm not saying you should never handle an exception, I'm saying you should only handle an exception if you're actually going to handle it and return the application to a valid state, otherwise you're just kicking the can down the road and the problem will become increasingly difficult to diagnose.
      A bug causing an unhandled exception that crashes your application is completely valid because that's how you find the bug and then you fix it (e.g. in this case by assigning the object).
      If your bug causes an exception and you catch it but don't solve the issue you still have a bug, you will just make it harder to find it.

  • @cogwheel42
    @cogwheel42 2 года назад

    18:17 - "What is a big deal?" -- This discussion reminds me of my two core principles: First Do No Harm, and Write Code For Humans

  • @irrellevents
    @irrellevents Год назад

    The edge collission detection could also be as easy as pos.x

  • @DaddyFrosty
    @DaddyFrosty 2 года назад

    Knowing what actually happens in the background of your code is both a blessing and curse. Because once you know what happens you become insane worrying about what happens every tick. Every single operation feels heavy. But you end up making faster things

  • @MrAWilco
    @MrAWilco 2 года назад +1

    I think you had a really interesting use case for analysing null handling and nullability.
    I personally would have left it as originally written, for the following reasons:
    - If it does return null, something major already went wrong and you can't really recover. This also isn't the site of what went wrong, so you can't add much context. All you know is something bad happened in the past and your assumptions don't hold. You don't discuss how you could try and continue with that null, I think all you could do is transform the exception to provide better logging, and then throw it up to a higher level. (as it does with the virtual machine when you test it)
    - the most likely causes are design time issues e.g. You got the tag name wrong or the scene definition is malformed. Allowing the debugger to capture this location is probably preferable. Its interesting that you are using a run-time system to capture a reference to something that is essentially static. Because of this its probably okay to not do any checks in this instance, but other times where you are looking for entities created at runtime null checking should be included, with thought of how to continue or reset.
    The FindByTagName function would be an interesting use case for nullability specifiers. As in this code, I bet a lot of calls to it work on the assumption that the entity exists, and its catastrophic if it doesn't. There you could provide a version, e.g. GetByTagName, that cannot return null and internally throws an exception with better context directly, e.g. EntityNotFoundException. (Although you point out that these use cases may be better handled with your public field linking framework)

  • @Gymomanen
    @Gymomanen 2 года назад +1

    There is so much bloom, it kind of bloo my mind.

  • @arxflymusic4985
    @arxflymusic4985 2 года назад +2

    34:42 AFAIK this Bob instance named m_Bob will be allocated on the heap, because it is a member of the class, and the class itself lives on the heap

    • @MrKyokure
      @MrKyokure 2 года назад

      No, because it's a struct, not a class

    • @bity-bite
      @bity-bite 2 года назад

      @@MrKyokure That struct is inside a class, classes are reference types so that means they're on the heap

    • @MrKyokure
      @MrKyokure 2 года назад

      @@bity-bite you're right, how did I miss that 😅

  • @MirrorsEdgeGamer01
    @MirrorsEdgeGamer01 2 года назад +1

    Also, null checks, with if statements, now use **is** keyword, as **!=** could be overloaded.

  • @MoeGunz
    @MoeGunz 2 года назад

    I know nothing about any of this but I’m interested so I would like to see this continued.

  • @HobokerDev
    @HobokerDev 2 года назад +1

    Always two there are, no more, no less. A master and an apprentice.

  • @jokerpb4778
    @jokerpb4778 2 года назад

    In case of 26:45 it would actually gett rid of that branch because that statement translates into CMOV (Conditional Move) instruction which does not introduce a branch.

  • @vitluk
    @vitluk 2 года назад

    I love this. One minute you get good advice from Cherno, next one you get BOBB

  • @breachin82
    @breachin82 2 года назад

    Nitpicking on the for loop stuff, which is fun even if it doesn't matter, as someone who does C# all the time, my brain goes toward generic collections instead of having an array. This would avoid a messy 'classic' for loop as you could do a foreach. Taking it then a step further, assuming there's a reasonable way to store these items in a generic list, you could then use LINQ syntax to write something like, 'arcadeLetters.First().Emission = 0.75f; ' after the foreach loop. This makes it very expressive and readable without any harder to read indexing at all. And of course we are way beyond caring about performance, so we may as well have fun with it.

  • @davidjohansson8476
    @davidjohansson8476 2 года назад +1

    I'm with Timm on this one! Bobb with double b for sure!

  • @zenthr
    @zenthr 2 года назад +1

    Answering the call! I spell it "Bob". However, if there was a class to manage "Bauble"s, I might end up calling them "Baub"s in code.

  • @lengors1674
    @lengors1674 2 года назад +5

    Yay, the high guy 😃

  • @tommytomtomtomestini3894
    @tommytomtomtomestini3894 2 года назад +2

    Holy Lack-of-Refactoring Batman!

    • @semuhphor
      @semuhphor 2 года назад

      Refactoring? What's refactoring. :D

  • @krellon
    @krellon 2 года назад

    bob noun
    Definition of bob - a short quick down-and-up motion

  • @lucksterduck
    @lucksterduck 2 года назад

    Loved this video!

  • @semuhphor
    @semuhphor 2 года назад

    Good video. Thank you for putting this up. Maybe a more pointed review on some aspect with subsequent fixes. For example, you thought of using a state machine. Implement one then compare the code. I really enjoyed this vid (on a Saturday night.... oh... I'm pathetic.)

  • @alexitosworld
    @alexitosworld 2 года назад

    All the time talking about nullability is why I dislike languages that have null objects by default. Use Swift or any other modern language and the compiler will tell you what to do.
    Very good advice about controlling the scope of variable. 👌🏻

  • @rickcarpenter6951
    @rickcarpenter6951 2 года назад

    code review session is perfect. There may be more videos! :)

  • @Ezdiess
    @Ezdiess 2 года назад +1

    Great review. Please make video about state machine

  • @featherless656
    @featherless656 2 года назад +1

    Cherno: game engine! Me: trying to figure out what vertices and indices I need for a cube and it still looking like a hot mess

  • @criostasis
    @criostasis 2 года назад

    11:20 getting to where I use != more than == was a big jump for my programming in the beginning. Helped me think in more abstract ways and catch things I would usually miss.

  • @cazino4
    @cazino4 2 года назад

    Won't the C# compiler unrole the for-loop if there is an opportunity to do so? I seem to recall the C++ compiler doing this at times..

  • @brayansanchez2854
    @brayansanchez2854 2 года назад

    Glad you’re doing a new game engine. At the moment EA do not have competitors in their FIFA game and their game mechanics are horrible. Maybe sometime in the future you can create a FIFA project for the very large FIFA community we have. Trust me we are all tired of EAs lack of game development. Keep it up Cherno!

  • @gratux
    @gratux 3 месяца назад

    As a non-native speaker, the double b in "Bobb" distinguishes it from the personal Name "Bob" ;)

  • @bambosa4952
    @bambosa4952 2 года назад

    The comment about making bob a struct so that it would be on the stack isn't strictly true, in C# if a struct is a member variable (field or auto property) then it will be copied to the heap along with the object it belongs to, so you might gain the benefit of having contiguous memory but wouldn't save on heap allocations.

  • @devc_
    @devc_ 2 года назад

    Love your videos!

  • @calmchess0434
    @calmchess0434 2 года назад

    Runs, plays well. Looks really good. The code could use optimization. Does it leak memory? If it ain't leaking then is clean code really necessary? For me the answer is yes. I'm a little OCD about optimization. *** smiles ***

  • @lorenzvo5284
    @lorenzvo5284 2 года назад

    Oh no, your luscious lockes

  • @FreeDomSy-nk9ue
    @FreeDomSy-nk9ue 2 года назад

    I would've loved to see how you would solve that problem with state machine!!

  • @yayaskurt
    @yayaskurt 2 года назад

    What about moving a rectangle parent of all aliens, Width of alien max columns? And negate velocity.x and move it down on edge collision.

  • @DM-pg4iv
    @DM-pg4iv 2 года назад

    This is a good review.

  • @enigma7791
    @enigma7791 2 года назад

    Next week Code Review Elden Ring? Now that would be a long video.

  • @TheKastellan
    @TheKastellan 2 года назад

    oh c#, I don't even code in c++ so this is a video I can actual understand properly.

  • @semuhphor
    @semuhphor 2 года назад

    Yes ... State machines! Excellent!

  • @sparcplug
    @sparcplug 2 года назад

    Which visual studio dark theme is being used?

  • @L1ghtOn3
    @L1ghtOn3 2 года назад

    Got to love some C#, the language that helped me progress further in programming and able to go bk and restudy C++ in depth as It was too much for me at University as was C/Assembly/Verilog/Matlab, but going back to C++ is enough for now I doubt I'll ever use the others again, maybe C or Assembly but not Verilog or Matlab. Not the biggest Python fan either, has a massive following now as it's the reccomended starting language and fear most never leave it or go as far as JS and that's it, made a Django ecommerce site but just left me scratching my head asking myself why does this do that etc, I like to know exactly why something does something, the how and the why, suppose it's gd for smaller projects? JS is getting better ECMASCRIPT every year but still has quirks like Python, TS is more my thing though probably the C Types background. Anyway yeah do like C# a lot, Java as well no surprise, but C# is my go to language. 👍

  • @iSam21
    @iSam21 2 года назад

    Yay a new video :D

  • @andreasmusic1222
    @andreasmusic1222 2 года назад

    Can you make a course on how you type like you do at 10:45 please?

  • @npatch
    @npatch 2 года назад

    I mostly agree with The Cherno on the whole branch within loop situation, but I think way too much time was spent analyzing it with the current case which is macroscopically irrelevant. So even if the analysis on why unrolling the first iteration is sound, the gravity of its repercussions, in cases where the code within the branches and the loop is significant, does not get across.
    And that having this kind of thinking as a matter of habit, ensures you area always in control of things.

    • @npatch
      @npatch 2 года назад

      For the animation utility class, another point to make is that where you have too many places where you're doing the same general task, if you find some kind of core mistake which you have duplicated across many places, you have multiple points of failure for the same issue. That doesn't mean that you have to reuse everything every time, but for a task that is pretty much exactly the same, having the manager/controller/whatever enforces one point of failure, thus easier debugging.

    • @npatch
      @npatch 2 года назад

      If the aliens move as a group and never deviate from that (e.g. all of them move towards the same direction at the same time, while staying at fixed offsets with eachother), why not use transforms in the scene and set the entities at local coord intervals and leave them be and the animation happens on the parent entity which groups them together, regardless of whether its animation smoothly lerps between points of the screen space or jumps at fixed intervals. And rigid bodies have a way to be controlled by screen, so i don't see a definite reason to go through all of them since the engine will do so too, since all of them are also entities. Am I missing sth?

  • @x.x.alireza.x.x6645
    @x.x.alireza.x.x6645 4 месяца назад

    داداش کد مرگ فضایی ها مال کدوم بخش از زمان ویدیو هستش

  • @thatcrockpot1530
    @thatcrockpot1530 2 года назад

    Was there a gun pointed at Tim during the sponsor section?

  • @renaldi6210
    @renaldi6210 2 года назад

    I like your hairstyle

  • @fischi9129
    @fischi9129 2 года назад

    Me: watches video
    me after this video: for loops are bad xD

  • @agentgamma771-08-B
    @agentgamma771-08-B 2 года назад

    Cherno:- talking about how he wrote spelling of Bob "bobb"
    Le me(who literally writes 80% of variable/non essential spellings wrong) :- 😧

    • @agentgamma771-08-B
      @agentgamma771-08-B 2 года назад

      Example:- yesterday when I was writing a health system for my player in c# I wrote the spelling of damage "dameag"😂

  • @dimitar.bogdanov
    @dimitar.bogdanov 2 года назад

    Nice haircut!

  • @hamzaabdelal2305
    @hamzaabdelal2305 2 года назад

    I Think it's BOBB not bob
    .... btw.... what type of chicken was it?

  • @dcmayo
    @dcmayo 2 года назад

    Good jobb.

  • @fretje
    @fretje 2 года назад

    I like Bobb!

  • @garageman2236
    @garageman2236 2 года назад +1

    A big deal to Cherno is anything that knocks off the smallest amount of performance

  • @andsandzandsz
    @andsandzandsz 2 года назад

    It's called Bobbb

  • @softleafstudios
    @softleafstudios 2 года назад

    The compiler won't care about the bobb lol

  • @Harsh-rz8he
    @Harsh-rz8he 2 года назад

    Thank u

  • @nabeelsherazi8860
    @nabeelsherazi8860 2 года назад

    WHY IS NOBODY ACKNOWLEDGING THE HAIRCUT??????

  • @maxi-g
    @maxi-g 2 года назад

    y‘all are overdoing it with the bloom

  • @The5thUSER
    @The5thUSER 2 года назад

    Can we get a half hour chicken review?

  • @martonkos5775
    @martonkos5775 2 года назад +1

    I didn’t know that Post Malone have a coding channel.

  • @tantelou2996
    @tantelou2996 2 года назад

    rip glorious hair

  • @mracipayam
    @mracipayam Год назад

    My one of the future goal is working with Cherno. If i can do then i am gonna come here and edit this comment.

  • @josephlabs
    @josephlabs 2 года назад

    this is content.

  • @ThienPowChong
    @ThienPowChong 2 года назад

    if i == 0 doest hurt much actually... but if i == 0 && checkIfDatabaseConditions... then absolutely should put the 0 condition before the loop.

  • @PostNoteIt
    @PostNoteIt 2 года назад

    More reviews of games with more bobbs.

  • @museumofmoderncrap532
    @museumofmoderncrap532 2 года назад +1

    mans you cant get rid of your hair without consulting us