This video demonstrates a comprehensive code review methodology for evaluating game development projects, using a 5,000-line C codebase as a case study. The review covers multiple dimensions including code organization, platform-specific code handling (particularly Windows.h inclusion issues), coordinate system conventions (model-view-projection matrices), quaternion mathematics implementation, and state management patterns. The reviewer introduces a novel 'Claude hours' metric to assess code quality, estimating how long an AI model would take to generate equivalent code. Key findings include recommendations for separating platform-specific code, using proper matrix naming conventions, implementing robust delta time management for physics, and creating abstraction layers for input systems. The review emphasizes that high-quality code requires significant human judgment and cannot be easily replicated by AI, making the 'Claude hours' metric a useful tool for identifying code that demands substantial expertise.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
A Whole Game in One File? | Code Review with AntonAdded:
So, we're gathered here today to review the game and the code of one of our members called Spike. And we've got ourselves a nice 5,000 lines of C code, one file apart from the renderer.
Renderer is another 3K because it's Vulcan. It's verbose. But here, we're going to review mostly gameplay code and take a look at how it how it generally functions. And we're going to start off by looking at the game itself.
So, thanks a lot for Spike for submitting the code for the review.
Thanks a lot for Anton who's showing up to critic the code. Critique code >> and I need to have my tea to >> without but this was German and critique was the French.
>> I don't even know man. It's just European. All of Europe's just one.
>> It's European language.
>> It's European language.
>> What's the language? It's European.
>> All right. Uh so let me first share the screen. Here is repository. It's actually public. So everybody can go and take a look.
>> Follow along.
>> Follow along. Start. Of course, I am not logged in because like I so I need to be signed. But please >> stars, >> please start this repository.
>> Star and subscribe.
>> And here there's a bit of a read me.
The game is a suck band style game, meaning we will have uh as I will pull this over here. Here we already set up in the in the level that showcases some of the features, right? We're not going to spend too much time on walking through the overlord overworld and how how the game works. It's a sooan game with lasers. You see that there's this one lighter cube, which is the first one, and the other one is a backpack.
And I can walk through here and stop the lasers from beaming. And my goal teleported. And my goal is to, as usual in Sakaban game, move around the objects on the scene to make something happen and solve solve the puzzles. And since I have a backpack, I am constrained in my movements because you can, as we'll also see in a sec, it's um it's a 3D game. It's a 3D plane.
Like it's not only 2D. So, I can't now turn down. You see?
>> See the small wiggle? The side wiggle.
>> Yeah, it's frustrating.
>> But here, >> you can do it there. Yeah, >> here I can. So, >> tricky.
>> And now, now I can go to a special mode debug pines.
It was controlclick.
Hi everyone. Let me take a break to thank members of the show who made this conversation possible. Members get earlier access to videos, including longer unedited footage from live streams, as well as they're invited to our private Discord server. If you want to support the show, there is no better way than becoming a member on YouTube or Patreon. Thank you so much.
I will move it up here.
>> What's the goal, by the way?
So, normally you have a you start off from putting the box into a square like a proper soccer game. Yeah.
>> And now you do the same thing with lasers and you need to put the lasers shoot the lasers to the proper position.
>> But where are they? Like in this level, where do they go? Where are they supposed to go >> here?
This is a this is a debug level >> made especially for us for this stream.
Oh, okay.
>> So, got to got to appreciate it. And uh this is a debug level that showcases some of the things like here you have the ability to take the take the objects and put them on the level. And I can even uh I can even add things to remove things from the board like you see >> built in level editor.
>> Removing cubes >> hard pivot to Minecraft.
I can keep the mouse button and terrorize the entire level.
>> Okay. Okay.
>> Even enter a special view mode here.
>> Okay.
>> To show what it's really like.
>> Oh, is that like the actual game game?
>> Yes.
I unfortunately broke it because I spammed my keyboard because I don't remember the key bindings. Well, >> well, I think we got the gist of it. Or did you want to show off some other bits before we dive into code?
>> No, this was pretty much it. Uh, >> okay.
>> We we're not going to be covering like we need to focus on something. We're not covering uh rendering part at all. We have one file.
>> We have one file. I can show later on the renderer at the end, but it's a lot of Vulcan code. So um what my plan is given what we saw right given what we expect this sock game to be um what first of all what do you expect from the code what should be there in terms of like state management or like resource management what would you expect to be if it's going to be uh in a C language >> and it's one file >> and Then we're going to go through and see like some parts, some bits of it. Of course, we can't be diving too much, right?
>> Yeah. I mean, you can fit a lot into one file.
>> Oh, yeah. Oh, yeah.
>> There's a lot there's a lot of room in there. You can you can put whole games in a file if you really know how to pack them, right?
>> So, this is as m as much as it's possible. This game I actually didn't didn't show it off properly. Uh, so this game has a overworld in the style of I messed up something and I can't really boot up the game again. Uh, so this game has a overworld, meaning you go in this like meta level and you can drop into a level and then do the puzzle then and then you go back up and you go through this, right? So it has these two modes of playing like there's an a a meta level called overworld >> in the same fashion as order of sinking star from Jonathan Blow now >> or like games like Baba you where you have a bit of an like a overview where you can walk but by more >> exactly >> riptop serious >> by the way how do you pronounce serious >> I think it should be serious >> do you know what it is >> unless it's kus If we're talking in European language, do you know what it is?
>> No idea.
>> So now, now I can I can't remember the exact name, but it has like a it's like when you have a biological categorization of uh different >> Yeah. Like tonomies kind of thing.
>> Yeah. Yeah. Yeah. Yeah.
>> And you have under species there's something that starts with a G. Do you remember >> genus?
>> So it's a genus of cactus.
Absolutely unrelated.
>> Okay.
>> Toan.
>> I mean unless it's this is like a reveal you haven't actually gotten to in the end.
>> That might be it.
>> Yeah.
And all the levels I saw I looked at the code a little bit. It's like all the level data and stuff is in data files.
So sometimes >> people you were not supposed to what?
>> No, no. I just downloaded the zip cuz I was like, "Oh, I don't know if you're if I'm going to drive the code or you." So I just downloaded the zip and looked at the directory structure.
So all I know is we're not looking at like level code cuz sometimes when people do simple games, they just like shove the level in line into the source as well.
So that's why it's so small cuz there's a lot of levels but they're they're separate.
>> No, no, no. We we are serious here.
Okay. We're serious.
>> Serious.
>> All right. Uh tell me what are your expectations? Like what do you expect to see on the on more a detailed level?
Like it's Sakaban game. What do you plan to see?
>> Need things man. There's going to be things. And I think the the question is going to be is it like a densely stored 2D board full of stuff or like 3D board or is it more just like uh just a pile of entities and every cube is an entity cuz you can kind of go either way. There's not that many cubes in the end. So you can just shove them all in and then deal with that. Or you can just do like X, you know, width by height, maybe a little bit of height, little depth, I guess in this case.
um that gets you easier collision detection right out the gate kind of thing, but then you have to worry with fixed sizes and and so forth. So, I don't know that that's kind of what I would probably start with if it was me.
Um are we going to try to do code rating like we did for the other >> rating? What's code?
>> Like when we rate the code, we have to like rate the code >> rating >> because it's a review, right? We got to know like is this going to be is this going to pass? Is it going to be rejected? which which PRs are going to be blocked.
>> Yeah, but we have only one file. So, it's going to be tricky like how we're going to have categories like we can't be just like reviewing one.
>> We can just if defaf any code that is is blocked just if defaf it out. No, I'm just kidding.
Um, given that we're we're like rapidly transitioning into the AI era, I propose that the measurement of of code review is how many clawed hours a piece of code would take to write. So we like if it's really >> what >> high quality code it will take like many clawed hours and if it's like ah you know we don't need this then it's like low clot hours. What do you think about that metric?
But you mean like verbosity or?
>> No, just like quality. It's like if it's good code, it it presumably it can't be written by Claude very quickly. It's obvious everything can be written by Claude already. Like we're already past that, right? So every but it's a question of how long would it take Claude to write. So like the best quality code would take infinity time because it just can't write it and then it sort of goes down from there.
>> Okay, >> it's like man hours except it's clawed hours. Okay, so let's do it like this.
We're going to measure this in clock hours. Uh we're going to review it and at some point we're going to be like, okay, we've seen a system, right?
>> So we're going to do the rating and then we're going to end up with a couple like at least three. Three is a magic number.
Okay, we can't have less. Like that's it has to be three >> and uh at least three. So then we have like three things scored in clawed hours.
And probably people would be like but which which model actually you know like it depends but uh okay oh somebody is suggesting Anton hours it's good we should keep that and see see what happens next. Maybe maybe this one claw hours.
>> I have to put put my money where my mouth is if I do that.
>> Yeah.
>> All right.
I wrote like just a couple of notes. Oh, these are yours would be like, hey, first like that's what I've done like to to prepare a little bit like I got handed the code and I'm like okay what is this right like where do I go? Yeah.
>> So, uh since like it's not a PR that we're reviewing but like an entire thing, uh you need to understand like what is the what is the place where people decided to split the files and like some sort of modules and whatever here.
>> Is that how you usually review things?
Is that like you start high level >> if you like I got I got couple of submissions like four or five I think recently. Uh and I needed to be like hey what is it right? Like first of all run the thing see what is it doing >> so that I know like from the what it's aiming to do and then I try to map this >> to to what I see which is like the division split. I just go line by line.
Like I'm like, "Oh, what's up with that first line?" And then I just go in. I just follow the >> I just find Maine and then I go I'm like, "All right, let's see where this >> find you need to have this like structure of like where do I start?"
Like, >> yeah.
>> So quick quick look.
>> Yes, >> this might be not not visible and I don't know how to make it bigger. Um, so one build script, >> right?
>> Good.
>> Yeah.
>> And this is because it's because it's uh uh Vulcan, >> we're compiling our shaders.
>> Sad times. Sad times.
>> Okay.
>> It's going to be mostly in in a handmade fashion.
>> Let's say compilation. You put your basically couple of >> Yeah. Just go for it.
>> And bye-bye. Right.
>> No logo, 360, no scope, no mistakes.
Let's go.
>> We have a render series.
Actually, we have this this guy here.
So, this gives us a bit of an interface for what's going to happen, right?
>> Yeah.
>> We have two things that are related to Vulcan submit frame Vulcan draw. This is this is the render part. There's game redraw and this is for the resizing.
>> Mhm.
>> And there are two things that we're going to focus on kind of uh game initialize which is the startup code and then game frame expected.
>> I appreciate the lack of the lack of variable names. I'm feeling it.
>> Yeah, I know what that is. That's going to be the time. But that's like a bold move. It's like yeah, just give it a double. Why not? Vulcan submit frame bool.
>> That one not so much. Let's let's let's let's play a quick game of guess the bull. Um what do you think the bull is?
>> It's going to be some sort of force like >> force something >> force parameter do is I don't know what we can force here but >> I think it's going to be initialize.
>> Oh like cuz there's no Vulcan in it. So, I'm wondering if it's just like a knit on first frame kind of pattern or like restart some kind of restart or but then it would have been first. It would have been the first arc. I don't know. I'm gonna put my money on something like reinit or innit or restart cuz we get like n draw commands.
We get int and then camera.
>> The int is probably the number of draw commands.
Ah, because it's a C. Yeah. Yeah. Yeah.
So, this is an array. This is camera.
So, for the for the transformations and >> the pool is mysterious, man. It's like a Yeah, maybe it has something to do with the camera.
>> Yeah. Okay.
>> Uh, should we do then the quick check?
Oh, there is a Vulcan initialized. Never mind. It's probably not in.
>> This is Vulcan bridge.
>> Chat, what do you think? What's the bull What's the bull do?
M >> we can move on and leave it as a cliffhanger for later. Maybe we'll figure it out from the game.
>> No, I want to know now.
>> You want to know now? Impatient.
>> What was the Vulcan? Submit.
>> Submit.
>> Yeah.
>> Render models. Unexpected.
Highly unexpected.
somewhat expected for for for Vulcan cuz it's like you make all this stuff and then you're like, "Oh god, I didn't this is just I got to do this thing sometimes. All right, screw it." And you've been wrestling with Vulcan for like 3 hours and you got to go to bed and you didn't get anything done. So you're like, "Fuck it, random models.
Let's go." That's my experience with Vulcan.
>> Vulcan is a bad language for hobby development. That's what I not language API. That's what I really I tried to mess with it for like several years.
>> Do experimental shaders. Yeah. Yeah.
That's what this is what I'm saying.
It's like >> cuz you're like, "Oh, I didn't make my PSO and I need to make a whole new PSO, which means >> Vulcan, >> calm down. Calm down. Close the file.
>> Close the file. I've got to go away now." Okay. Got Vulcan PTSD. Vulcan was supposed to save everyone.
>> No. No. No. We don't. We don't go. We don't go there. We don't go there. Okay.
Okay. We don't go there. Game play code.
>> Okay.
>> Okay. Okay.
>> Uh I I suddenly found myself here >> in time. Yeah. Just got out. It just got out.
>> Open the first door that you saw.
>> So you can rant here. I would say way too many characters. Way too many.
>> You ate. You're You're more of a I ate you ate kind of guy.
>> I am like this.
>> Okay.
I like >> um I've kind of I I've entered inner peace and I I can even go like my code is now mixed. So I have UA and A and U8 U and A T and I'm like yeah it's all good. They're all the same. They're alias in my >> family. They're family.
>> They love each other.
>> Pick whichever one looks better in the context.
>> Here my question, my immediate question.
I see this as a higher level uh uh not in the language not like a quality but programmer where where are my operations man where my like pluses >> see man you don't you don't get operators in C >> I know >> but if you use the clang extension you could so there's a clang vector extension that will give you >> the glsl vector types in C I think it's C99 extension that. But then it's like it starts to feel like uh if you're doing C99 with extensions, you're basically doing C++. You're just sort of in self-denial at that point. Like it's >> No, maybe you want to have like 40% quicker compile times.
>> Yeah, that's true. That's probably true.
>> And you don't want to be tempted by >> you want to resist the urges. Uh I think it doesn't give you int or bull types I'm guessing. I think it's just probably floats. Maybe it gives you ints. I don't know. Um yeah, the operators are going to be functions, man. Not going to get This is basically the reason I don't use C in practice. I end up using C++ basically for operator overloads on vector types. That's like 90% of why I use C++ because I want to write math code that is both easier to read and also it would I I do a lot of cross compile. not a lot, but I do some cross compiling between um C++ and GLSL or whatever shader language is. And so I just like to include the same exact code on the CPU and GPU, especially for things like random numbers and that kind of stuff. So having operator syntax is like pretty key for that. Um also just hate typing mole add and all that. But I don't know, it's a personal thing.
I uh somebody mentioned that I my my mic is lower and your yours is higher. The only thing I can do is lower Anton's mic. So I did that and uh yeah I cannot I cannot put more power. I can only scream.
I >> So people my my take here would it mean then like add should be here like a function definition like at least declaration shouldn't be here.
>> I mean you never know if you're going to need ad. You might not need ad for all of these. Just just do it as you go, man.
>> Really?
>> We'll find we'll find out. We'll find out.
No, I So my guess just reading from this since you know I think Spike mentioned this is like he's just starting out with this this feels like following along from Handmade Hero kind of vibe and so I suspect this is the beginnings of like building out that library, right? Cuz um it's got a couple of these but not like all of them. And so I suspect it's like all right, let's start building out my log cabin vector library. and just hasn't gotten to the the operators yet.
But we shall see. We'll find out.
>> We shall see.
>> Maybe he's like a raw dog vector kind of guy and just goes goes for it with with the raw member variables everywhere.
We'll all right this was this was types and you remember that we had also world states strcts and apart from these two separate files we just serious C. Okay.
>> All right. Should we check the strruct header or do should we just go straight to the to serious?
>> I think we should check this and then >> let's do it. Let's find out.
>> Spend spend all night there.
>> Okay.
>> Okay.
>> So, >> Windows is defining void to void.
>> No idea.
>> Windows. I have no idea.
>> Windows naughty naughty Windows.
>> What's going on? Anon. Anon. What is going on?
>> So, Windows.h. So, somebody included Windows.h. But this is a little bit sketchy because like why did we include Windows.h somewhere? That should be only inside the wind32. So, I guess maybe this goes into the >> who included it.
>> Serious.
>> And I see the comment temporary next to it.
>> Yeah. Yeah. There it is.
>> For debug. Oh, no. Um, yeah. So, Windows defines all manner of crap and it just like trips you up. Like it defines like rectangle, I think. So, then you you inevitably someone tries to make a class called wrecked or rectangle and then you get like these Byzantine compile errors because it's a Windows macro and you're just like, what is happening?
So, anyway, so people just undef stuff, but that's why you don't want to include Windows.h anywhere. Um, all right. So we got some platform render handles. Okay.
>> So this one this one actually is a big one. So we might not need to go through all of it. There's one thing here that is for me skeptical and I need advice from >> Anton. Okay.
>> Sure.
>> So let's go. So we have couple of strcts. We go there.
>> Sprite ID perfectly normal.
Understandable. Cube model.
draw command sprite ID S type this is like okay we don't do we don't do rendering so we're not going to spend too much time here we have camera yes okay that's all that's more our zone but generally speaking we'll come back on the gameplay code I think and then we go tick input and then I do papa >> oh okay >> papa >> okay >> papa You're okay.
>> So this to me >> uh-huh >> is wasteful in terms of memory. you have a lot all of them and you share bool which is like one bite eight bits and you can have this packed into bits separately right that's one case >> and then >> maybe because I'm just too library skewed but at this point like it feels like hey we're doing our framework and we're defining everything right >> if you were to do your project If you're doing this handmade way, that's that's the way to go, right? You need to build yourself everything, right?
>> But at the same time, where would you go for a library to handle some of this stuff?
>> You mean if you're building the library for where you pull this kind of stuff out?
where if you if you go for a project, right, would you consider doing things like, okay, hey, I'm going to need this and that library and I'm going to so to avoid doing this, right?
>> Yeah.
>> Or you're going, hey, I need all of it and I'm going to even handcode the nine press case for my tick input. That's that's like to at some point you need to stop because like whatever you're doing is not going to ship if you're like I actually need like 16 press case for like this very particular specific platform. So for me it's like when do you say okay uh I'm not going to bother with this until I reach this case.
Well I mean there's like two separate things going on. One is that this is wrapping the raw input coming from Windows, right? So, it's sort of like repackaging it as a massive bull struck.
Um, that's not a good idea. This is this is sub one hour claude code.
Um, so but like forgetting the bid packing side of it, which you can do to save space, but it probably won't matter in this case. Um, often you want to write stuff like, you know, when when you're writing especially debug or or simple code, you're like, oh, if the user pressed something between 0 and 9, take like the key they pressed, subtract zero, and that's like your index between 0 and 9.
So that's really useful for like hotkeys or shortcuts or or if you want to do really simple text input, you just say, oh, what's the in what's the letter? Oh, is it a keystroke? Subtract like ask key A. And now that's like my character code or whatever.
So having it with bulls precludes you from being able to do these kind of like index based things around um the key presses. So if you look at like SDL or GLFW or any of these frameworks, the reason they define all the keys as enums is because there's like naturally useful ranges in there where you can just be like, oh, if I know the key presses within this range, subtract the beginning of the range and now that gives me the index inside the range. And you can do some nice coding compaction based on that. But this is nice for autocomplete. You're like, what what's it called? Is it SDLKM or is it SD keym?
I never know, right? And so this would be like inputs dot and then it's like which key do you want? M press. I got it. So I think it's coming from that vibe where it's like I don't want to remember no enums. I just want it documented. I don't know man. You do you. But until you until you find like yourself feeling like man what I really want to know is it like between zero and nine then you start anything programmatic. Um but in terms of like should you wrap it? I I think it's actually not a bad idea to wrap it somehow. Even if you're using something like SDL um just pragmatically, I've had projects that sort of lived on for years and then I had to swap from GLFW to SDL or from SDL to GLFW or to something else and it's convenient to just be like, yeah, yeah, yeah.
So this is always as an example given on the internet and I'm like bro if you're serious about the project and you're like 3 years in and you have like a production case and you have clients like are you going to like switch from GLFW to SCL like at this point like I I always like for maybe hobby projects or like something you know >> this I understand but >> this case like always like Oh, it's going to be so nice. We're going to draw the UML diagram. It's going to be an abstract interface and it's going to replace like >> you don't need the abstract interface, but it's useful to know like SDL is huge. DFW is huge and if your app is only going to use a tiny portion of it.
Um, I mean, yeah, it's questionable. Uh I guess all I'll say is I have projects in which I you like ages ago. Let's say I take like a project for from 10 years ago or something like that and it's written on top of SDL2 and it's got SDL2 code everywhere and the key strcts are using SDL key enums and the this sound is the SDL sound. I'm like ah this project sucks man. I don't want to like I never want to revive that, right?
Because you're like, "Oh, I have to >> get So, if I ever want to modernize some piece of that code, it requires me to to fix up a lot of SDL stuff." Whereas, if it was put away, I just be like, "Oh, I'll just fix, you know, my input.h or my input CP or whatever." And then it's fine. And also, SDL and GLFW are kind of like allin-one things typically, right? So you got your graphics, SDL also have sound, you got your input, but if you ever want to like put it on another platform where those are not part of the same library, then having your own platform layer is handy.
It does feel like wrapping a wrapper, but I don't know. I think for longevity, it's not a bad idea. I just wouldn't quite do it like this. Uh, now I'm gonna be sneaky because I've seen parts of the code and I'm going to talk a little bit about things that we didn't didn't show yet. But this stick input is actually a parameter to G game frame.
>> Okay.
>> So, it's not like there's an instance and you switch what's pressed.
It's actually being copied every time there's an invocation for a frame.
Okay, thoughts.
>> It's fine. It's not going to kill anyone.
>> It's huge, but there's one tick per frame, right? Presumably.
>> So, yeah, it's a whole pile of stuff on the stack, but it's all fine. You have a lot of stack space. It's not a big deal.
Not a big deal.
>> Damn. I expected like a huge Ah, that's sketchy. Ah, >> I mean, just pass it by pointer if you you don't want to. Yeah, it's okay.
These are not the things that will sink you.
These are these are shallow bugs or or shallow kind of like issues, the stylistic issues.
Okay. Um, Windows.h on the other hand, like that man, you include that, that'll get you.
You don't know what's coming in with that. Oh, for macro.
>> Why do you why do you say that? Uh meaning you I know that's like a easy thing to say.
First of all, Windows.h has been the go-to way of interfacing with Windows like yeah >> two decades ago, right? Since then there's a special flag called like win and mean lean and mean.
>> Lean and mean. Yeah. Yeah. Yeah. Yeah.
>> Yeah. It's like oh now it's going to be better.
>> But at the same time the Windows 8 was split into various headers >> like manip or whatever depending on what your use case right >> sure >> but are you saying including any of them is very sketchy?
>> No you have to include them somewhere.
>> Yeah. You just have to include them in their own little like self-contained bubble so that nobody else includes them. Like that's the first thing you want to wrap is is that stuff cuz I mean Windows.h just has everything in it which is convenient because you know you kind of just want everything and you don't want to always look through the docs and be like oh I need to get this Windows H file. It's like okay I get it. But it means that if you put it into a major header or your main file, you're now incurring like a bunch of crap into every file and it will mess up. It will come with surprising gotchas and stuff and uh I guess lean means probably better. So I I just I make it a point to be like, okay, I would only include that inside win32 serious or something and just only keep it there.
>> Never let it leak out. not in the like crossplatform part. Uh >> yeah, just the platform layer for wind32. Never like bleed it out of its its own file. Ideally, just one file or whatever just so that it only pollutes the one place. And if I search codebase for Windows.h there should be exactly one file that includes it is sort of my my general policy. That's I mean >> that's the case because here's here's Q is commented out and the other one is not commented out.
>> Another one I saw the is that oh the one in series is commented out. Yeah. Good.
So there you go.
>> So basically that's it.
>> Yeah.
>> It's also a bit easier if you have two files like >> those are in those are globals though.
That's a little bit weird.
>> Oh I guess it is global window handle.
Okay. All right.
Uh, that's probably why it's leaking out for debug.
>> Also, was bleeded out a reference to I think Linking Park or >> No, just just imagine it spewing from >> Okay. From from a tightly contained place.
>> I need your thoughts on this one.
>> Hey man, I wrote a loop macro for my old projects. I'm I'm all for it. Try it out. See how it goes.
>> I'm all for it.
Um, I think in practice this doesn't play out. I think it makes things harder to read, but I think it's fun to play with.
>> Like over time or what? Like when the project or what?
>> No, just like over time. Like I I thought this was cool back in the day and then cuz I kept typing it over and over and over. But then what I tend to find is that there's enough of them that are different uh as you start doing more and more complicated for loops uh and then it becomes weird cuz now you have your simple for loops and your complicated ones and then it's like why do I have two things you know so that's kind of same same problem I have with like for each I've tried to use for each in all its C++ incarnations like tons of times and every time I write it and I'm like, "Oh yeah, I just want to iterate the stuff and like call update on it or whatever." Great. And then every time something is like, "Oh, I need the index of the item." And it's like, "Damn it, now I have to change it to a standard loop." Or it's like, "Oh, but actually I want to skip some items." It's like, "Damn it."
So yeah, basically I just almost never use that at this point unless I'm like you know you using some kind of standard container cuz I'm being fast and loose and I'm like I have no idea how to iterate a standard hashmap. Let's just do it and just all I need is to print things out or whatever. But generally I just write the raw for loops because of that.
>> Okay, >> direction. Okay, now this is where I'm going to uh stop scrolling and jump directly to main because I think it >> but these are important.
>> These are useful.
>> Yes, but there's a lot of them.
>> Yes, there's a lot of Okay, but let me glance at them at least so that I know what we're dealing with.
>> Okay, >> just scroll down and I'll just sort of >> Okay, >> take take a slow trip down to Maine and I'll narrate the slow trip with with things that I'm that I'm spotting. not main it's win main and it's different file but okay >> okay okay okay >> let's do it so type dev enum since it's since it's a c >> we don't know what it is yet >> see we'll see on the at the end >> see you on the other side >> I guess zero >> and this is what you meant right like you're going to say here >> this >> and now you can do like source white minus >> source red and be like >> that kind of stuff is good for keys as well. Yeah.
>> Okay.
>> So, >> so I saw the direction. Can I see the direction real quick?
>> Can we just start from the very Yeah. No direction negative one is already giving me like a red flag of like better watch out for direction. Anytime I have to compare things to negative 1, it's like why is north zero? Probably cuz it's in an array and they wanted to use zero.
We'll find out. I'd rather burn an array slot for the zero slot than than deal with negative one these days. But but I get it. All right, you can keep scrolling. I'll just keep talking while you scroll.
>> No, actually now we have like direction >> and then we have up and down >> because we in 3D, right?
>> Right.
>> Okay. like this we need to remember but it's not 2D because sometimes up it would be up but like it's actually >> dimension >> and I am okay so when I see this now uh >> in my like proprietary code at work >> I'm like hey can we not express an invalid state and get away with having an enum for a state that's very often like you have an enum for something that's related to the state. Can we just like not express an invalid state anyway and have it always be valid?
>> Meaning like skipping the non or like non-existent or invalid things for the things that cannot be invalid through the lifetime of our application.
>> So here it's like a sentinel value but maybe here >> like what if what if we never had this value to begin with? Yeah, that one that one that's why I'm saying in particular for direction I think I'm a little bit concerned.
We'll see. We'll see how it's used.
Also, I I think I prefer to put those kind of things at the end, but it depends. So, like I would make no direction be like six or something or I would add like direction count. Yeah.
Yeah. One sec. Let me let the cat out.
Cat is trying to escape. Let the cat Let the cat out of the box.
Oh, look at this. Anton has like a steering wheel wheel.
Yeah. Like the reason I like to Oh, yeah. Yeah. Yeah. Yeah. No, I thought this would happen. Yeah. It's kind of like it's basically used as a value for I I don't know which way I'm going. I didn't get a response. That kind of thing.
>> Yeah. But like you cannot be rotated in a direction of no direction, right? So like even if you don't know then you can signify this with an error. It was with an invalid state and like hey your call didn't succeed.
>> Yes.
>> But as far as the values are whenever you have them there should be >> you don't like it >> functional. At least I that's my like give if you have a system where you cannot be in the invalid state why would you add another thing that you need to always keep in mind and always check for >> and your entire application should never ever use it anyway. That's >> I think I I agree with you at a high level, but when I'm going fast, sometimes I'm like, >> "No direction. Let's try it. Maybe it'll work this time. Come on. One more try, bro. Going fast." Yeah, I'm going fast.
Sometimes you don't know. But yeah, I think you're right. It's It's very often doesn't pan out. So, we'll find out through the code.
>> So, for example, here if whatever happens here, here maybe it always sets the direction. Let's say go else we here but we never hit this one. We actually go next section. Let's say that there will be a case where we exit this function with no direction. Now we need to check in whatever was calling this function.
>> Totally.
>> All right.
Uh where are we?
>> No color >> tile type. It was style type each enum.
>> Mhm. Then we go enam color. No color again. Skeptical.
>> Not a fan.
>> Let's leave that down. Struct.
Okay.
>> This is green. I'm assuming green laser.
And Spike told me lasers are new. Okay.
So there might be some rough edges lasers.
>> So it's only green lasers that do things.
>> Yeah, exactly. No, actually they have No, they have different >> um mechanics. Green one is the one that teleports you.
>> You can you can teleport.
>> The other ones uh do things with the um >> I see >> with the mirrors.
>> Okay.
>> Uh reset info.
>> Mhm.
>> Reset blocks which aren't currently active in the game. Chords are integer coordinates of the entity position known as floating point world space likewise direction six direction past renderer.
Uh since since since since Spike mentioned world space I have a question.
So if you are in gamedev world, >> you have various coordinate systems >> and often you represent a position or rotation um through a vector.
>> So you never know what is the coordinate system of a given vector because it just floats. And if you're using an engine like Unity or something, there are some sort of conventions that you can adapt.
If you're making something from scratch, uh I would expect that there is an answer for a user of the code like developer to know at what coordinate system we are at any point in time either through a convention of like prefixing names or whatever or something. What's your take on this?
>> Yeah, you have to have that. It will save you save you time in the end code.
Would you encode it in a type or something or >> No, no, no. Never the type you because a space is not really a type, but definitely a prefix or a suffix um is is sort of my convention. So I follow like what's called the domino convention.
Um so if you have for example like a typical do you know about the domino convention for multiplication? Okay. So, so you have a bunch of m so typically in a game or any 3D application uh eventually you render in something called clip well your graphics will end up in clip space or NDC or all these things right and so it's something like at a high level you have your projection matrix then your camera matrix and then like your model matrix so sometimes people call model view projector projection not to be confused with model view controller different place. We have model view projection up in here.
>> To be more confusing, you often spell it out as PVM because you need to change the direction.
>> Yeah. So, so here's what I would propose to you if you want to like type really quickly and then you will see the light immediately. So, you're going to have some kind of matrix which is called like projection, right? So, or maybe I can can I hijack this screen briefly or do you want to do you want to type cuz I'll this will save you time. This is a good convention.
>> Let me type like one one.
>> So, just like get a bit of blank space and then I'll show you some kind of like how this arrives. So, so you're going to have a projection matrix somewhere, right? So, let's call that projection for now cuz you're like typed one like this.
>> Yeah, let's just call it projection.
Right? You're going to have uh a mat for uh view and then you're going to have another mat 4 which is like model.
And so typically model is going to be like where's my model in world space and view is like how do you go from you know world to view and then projections like what's my FOV and all these things right? But notice you have no freaking clue what is it view is it is that like the position of my camera in world space or is that the matrix that takes me from world space into the view I don't know and that's what you're talking about right and then you have position which is like let's say it's like a vertex inside your model or something right or like a point inside your model so now leave that there as a point as a place of shame and then I will type the correct convention for you below it's going to be more wordy but you have matt for projection from view like projection underscore from view and then view becomes uh matt for view from world and then matt 4 world from model and then lastly vec 4 model position or Pause.
Right. So now using those domino pieces I just gave you, can you construct me the model position in projection space?
>> Of course.
But how do I need to name it?
>> So now you call it model projection.
>> Ah because we we we have the suffix.
>> Yeah.
Okay, there you go.
I think I see the pattern.
>> Yeah, >> raw model.
>> Congratulations. You're now a graphics programmer. You'll never make a mistake with spaces ever again. Like, and you've used zero brain power to figure out. And now you can be like someone's like, "Hey, can you get me the position in view space?" You're like, "No problem."
Or like, "Hey, I've got a position in clip space. Can you take it to model space?" You're like, "Sure, I'll just invert a couple of things." So when you invert something, it flips the from order.
>> And then you can look at any piece of code and if the view if the two things on the domino ends don't line up, you've got a bug 100% every time.
And so like whenever I would go to studios and I would do like VR debugging like when VR first started coming online and people until VR this you could kind of get away with being like well I got three matrices I'll just figure out the order and usually they have a little bit better naming than just view. Um but sometimes people like to use model to world and if you do that your dominoes don't line up. So if you imagine cuz the like if you had view to projection or view to world or something or world to view it doesn't line up this way cuz you the multiplies go to the right. So the from is the kind of key thing that tells you oh things on the right go to the left.
>> So I fixed a ton of bugs just renaming vector. So I'd show up and they'd be like we have a bug with our VR projection. I'm like show me your matrix names. And they'd be like all random.
I'm like we're going to rename matrices.
Like no let's just fix the bug. I'm like, "No, no, no. Rename the matrices.
All the bugs will just fall out." And then it's like, sure enough, many bugs would be discovered and just fixed immediately. And uh so that's the correct convention. Um the the last ve 4 thing is kind of annoying.
Sometimes I do position underscore model because it's like but this is the one that is is is the most um you mean position underscore model here.
>> Yeah. But then you already will get the heebie-jebies cuz you're like ugh everything lines up so nicely except for that one. But people like to have the more kind of like because then everything just becomes everything is model something or local something or world something and it's like when you read it's like world and you're like gh >> so it's kind of annoying. So for those things it's it's annoying but for matrices it's 1 million% worth it. You will it will save you from many many bugs. Um >> okay nice. Yeah, I actually when you started saying this, it's like oh actually it's super easy you remember that model is this and the model is that and then I realized that I made this mistake when like I had a model matrix and when you think about this model as a model you have a object space but it's not easy to understand that the model goes to the world space right and it's >> and exactly >> yeah so I think that's and it's even more the case with cameras cuz it's very common for people like half the people will think of cameras as as like a position in in world space somewhere which is like the more intuitive things like where's my camera floating in the world but typically the the traditional view or camera matrix is actually like a look at matrix which is actually the inverse of that matrix and so you just never know you look at a piece of code and you're like that's the camera matrix you're like which one I I don't know >> and then you name it this way and you're like world and then it's really easy like if you have an entity it's world from camera. Oh that's your camera matrix. Oh great. Well how do you take things into camera space? Well you invert world from camera becomes camera to world multiply by any world vector.
Now it's in camera space.
Yeah. Nice.
Nice. We're reviewing strcts.
We're now reviewing stracts. We didn't got to main yet but we've got a lot of tangents. So here we have a cool one entity.
Entity first of all already done. This is like the classic fat scenario >> where you start to dump all your like okay I have this kind of corner thing I need to store. Okay let's go.
>> It's in there. There's the space for it.
Removed >> rotation. Yeah I mean all looks looks about right. Next level 64.
Oh, it's like next level name or something >> to do make level names as enam. So don't need to carry around 16.
>> Yeah, it's fine. You don't have that many entities.
>> Yeah, it's all good.
>> Now here one >> two. Now that's a buffer right there. D That's not actually 2 megabytes.
That's 2,000 by two. That's 2 million bytes.
But but all right. um uh okay >> so we have we have a world state >> world entities right so this is like the thing we're going to get into okay I'm not going to spoil it okay you're not going to spoil it >> but you they're going to h they're going things going to happen okay >> okay two bytes info per tile okay and it's a buffer two 2 megaby dense buffer representation of the level encoded by coordinates encoded by coordinates.
So is this like okay so m maybe it's x and y indexes into that but why is it a u8 okay question marks will be left around that area okay and then we have a player we have 64 boxes 64 mirrors 64 things of stuff and solved levels is 64x 64 so it's just a bunch of names yeah I mean I would probably make those 64s into a define of some sort, but that's just me.
Um, let's see.
>> So that you can reference the max one.
>> Well, it's just because here you've got a bunch of 64s and here some of the 64s mean 64 characters in a in a name and some of them mean 64 entities. And at a glance, if I was modifying this code and I'm like, "Oh, you know, I want to make my names long, well, I want to make like more entities or whatever, I might accidentally hit the other 64s cuz they're not like the other 64s." So, that's kind of >> my my question is, are you pained that all of them do not share like one single array with a type?
>> No. And then no, it's totally switch.
>> No, it's all fine. That's all right. I'm much more pained by bad matrix naming than I am by by this kind of stuff.
Yeah, why not?
>> So, we're not like we're not uh lamenting that we didn't find this like thing. I don't mind. So, I think it's it just it depends on how you want to think about it. And I think >> I mean I guess one thing I'll say is that it's a little strange that it's this and that it's one fat strct cuz you might as well just have boxes box types and just have 64 boxes if you're going to go this way cuz they're not sharing any stuff. But I suppose it's convenient to pass things around by entity and have like some type eraser that way. Um, but I think having things sorted by type, if that makes the code easier, cuz if you're iterating over types of entities all the time, and that's an easier way to think about it for you, that's fine. Where this starts to fall down is if you want to do something to all the entities. So, you end up having a bunch of code which is like render all my boxes, render all my mirrors, render all my sources, and it gets a little bit repetitive. And I don't like managing that kind of boilerplate. It slows me down to like insert that kind of logic in multiple places. But until somebody feels that pain and considers it pain, like you can't convince them that this is a problem. So like I'm kind of, you know, >> slow potato.
>> Yeah. It slows me down.
>> We got to go fast.
>> We got to go fast. Um, so I think like that first talk I saw from from you with like Billy Basso, he talks about using a macro for this kind of stuff because he basically has this structure, but he's like my solution to being slowed down is I'll make it a macro and then it inserts in four call sites at once. I'm like, yeah, let's do that. That's good. So I I would say that's the that's the next evolution in that Pokemon tree where if you want to go named separate arrays like Billy got you covered and if you're like I don't want those macros I just want one thing of things. It's like all right that's like more of more of my camp.
Okay we're going to come back to world state.
I'm going to keep this in mind. Um, okay. Now we have couple of things. Uh, trailing hitbox animation.
I think we can come back to with the gameplay code push result.
>> Okay.
>> In terms of pushing the the pushing the box, right? It's a soccer band game after all.
>> Yeah.
>> Got to push.
>> Got to push.
um pack turn state. So pack is a short for a backpack >> short for the thing you carry meaning the other one. So you you play as a player and then you have >> uh >> that's your backpack >> backpack.
>> I thought it was like the packed state and I was like oh we're doing some bit packing but not really. Yeah, it's it's the pack >> game progress world zero world one gate one.
>> Okay.
>> Editor structs edit buffer editor mode.
So this game features undo and then reset level.
>> Okay.
>> So all of the all of the levels and movements are um serialized and so >> good. Her state writing field camera mode rcast hit pop-up type >> cheat mode >> popup >> lasers does cheat mode toggle >> yeah laser color >> that's a color >> questionable >> well you know things things are >> I guess this allows for you know reddish green lasers which is good like you can have las yellow lasers by doing a red green >> almost immediately you would like you would like to have a normal color representation via vector so that you have your own operations on the vector for colors and then you can have couple of constants with like hey this is my green for laser this is my red >> well it depends on what this is for if this is like the color visually that's true but if this is Um, if this is the logical version, which is like, you know, the game logic version, like you're saying the green lasers operate differently than red ones.
Then you don't really want this to be a VEC 4, right?
Or a VC 3.
>> Yeah, but I would say like this is the visual representation. Maybe >> I don't know what it is yet.
>> It could be visual. Sorry. If then then it should be an enam for the type.
>> Who knows? We don't know yet.
>> Or may be it should be a trait, right?
Because it can be both.
>> It is.
>> That's what I'm saying. Maybe green l maybe something can be green and >> red. We don't know.
>> Okay.
>> Can't judge too early. We can't judge prematurely and then we will judge hard hard. And we need to at some point we need to do like the claw hours estimate.
I don't know what how to do it.
>> I think this has very high claude hours because I'm not sure Claude would like this has a lot of game knowledge baked in. So I think this is a this meaning what >> like everything we're reading so far although it's kind of like just enums instructs this contains like the design of things.
>> You know what I mean? to get to get this printed by Claude would require like lots of prompting and lots of back and forth between Claude.
>> So even though there's not a lot of lines, >> we're going to do undo. Then we do only these three strcts and some functions, but not like all of them, right?
>> Yeah. And we need laser colors as opposed to like, hey Claude, wrap SDL input into a bunch of pools.
I would do it right away for you. This one is like I don't know. What >> was this accent?
>> That's my That's my Claude accent.
Claude hours ranking. All right. So we have wrapping input hash custom >> input >> systems.
Actually that's hashtag. It needs to be like this.
>> Yeah. Um, so and then we're going to have type defin all the >> you know you remember this meme of like all the things and like yeah that's that's the reference. Okay, your how we're going to doing the estimate chat chat, we need your estimate.
>> We need your estimate for cloud hours of prompting like relatively high cloud. Okay, we're not going to do like, you know, high cool clots.
>> Um, wrapping input custom input system.
Um, how much hours of workload to do it, right?
and you also think about it. And then let's do like let's do the countdown and then we both type in chat.
>> Okay.
>> Okay.
Oh, are we going to Oh, I I'm not signed into chat. I'll just say it.
>> Okay.
>> I don't know.
So, I think for wrapping input, >> are we doing discrete hours? Like it's got to be at least an hour.
>> Yeah. Okay. Yeah.
Okay. I have one.
>> Okay.
Three, two, one.
>> 1 hour.
>> One. One hour. Definitely.
>> Okay. Okay.
>> Yeah.
>> People are like 40 minutes.
>> I mean, yeah, it's probably like more like 10 minutes or 20 minutes or whatever, but we're going to >> 1 hour.
>> We have a lot of credits, you know.
We'll we'll ask it to make no mistakes.
zero bugs, man. Like all >> be like write the tests, you know, do all the good stuff. If it's less than an hour, just spend the rest of the time making it better cuz it can always be better. So >> it can always be more std as you know after your recent experiment.
>> Yeah.
>> Okay. type deving all distracts then like the thing is I am a little bit skeptical here with the the claude hours analysis because it w did not come as a single task >> right >> you know it was it was a part of of implementing a let's say undo system so you only do undo once >> but if it was like hey I need to lay down the foundation okay just in like abstract way >> do all is how much do you think would have been in CL hours? You can tell me your first uh impression and then I would tell you mine.
Well, I think that's the thing is that if uh the first draft is always 1 hour, the interesting part is how long it takes to get to the real result because like you get really good oneshot things from Claude all the time. Um, and if it succeeds in the first try, you're like, great. But if it doesn't succeed, that's where I feel like all hell breaks loose because it's either going to make it there in a couple of tries or it's just going to be spinning and you're going to be spinning and >> spinning tokens, >> spending and spending those tokens. And so I feel like Yeah.
So I I mean I think the initial I don't know. We'd have to get to the main. Did we get through all the type defs almost? I think.
>> Yeah.
>> Uh I think we stopped on something like 350.
>> Yeah. My my feeling is that it it would be faster for you to type the strcts than it would be for you to def to actually describe all of these strcts.
That's my opinion.
So I think you'll sit there for an hour typing in specifications, but I think the overall thing is going to be like effectively as fast as you typing the strcts, >> which might be hours.
>> I think this one is something between 10 hours to 20 hours.
>> Yeah. And my take is that whatever you're going to do through clo it will add the things that cloth thinks should be there >> that is not at all aligned with your vision and the more time you will spend just understanding and way I actually don't need that at all like but it looked really good like it looked really nice like from an example but like no actually I don't need that >> so it going going to be more like messy to to handle though handle >> what is going on.
>> All right.
And did we should we breeze through the rest of the strcts and get to the get to the code now that we kind of get know the lay of the land a little bit? So and stuff when and stuff finishes and like we can we can look at and uh separately I think as a system >> and now we enter into globals and then functions.
So globals everybody this >> tow spotted I'm I'm on it.
>> I I'm two pie team.
>> Oo I'm a tow kind of guy.
>> Okay.
>> Okay. very well. Um, display.
>> Mhm.
>> Okay. Ton tons of constants. I don't think we're going to go through them each one by one.
Camera sensitivity camera. Oh, and one thing that it's important to mention that here are the uh is also the state initialized, right?
>> What is it? I actually don't see it now.
Ah here >> right.
>> So it's all zero. Yeah.
>> World state. So this is zero initialized.
>> Yeah.
>> As expected from a clear handmade hero descendant.
>> Yeah.
>> Zero initial.
>> You don't even have to do the little zero, right? Because >> um you mean this >> statics are zero by default. No statics are zero by default. And see >> okay. But um I like the explicitness cuz it's basically kind of saying hey it's going to be zero. So this is basically in the program our like entire state right and >> given that we have one file.
>> Mhm.
Pretty much. Why would we do this through static?
>> I don't know.
So, I'm not sure, but and I also saw like a surprising lack of statics in the platform layer, but um honestly, I'm not I think that there might be things in C with static that I maybe I'm forgetting.
So, I'll kind of chalk it up to that, but I'm I don't really know why why that's there.
>> Okay, we'll just leave it. This this basically makes it like global but at the same time you have a draw command >> but the globals don't matter right >> yeah okay good >> yes someone pointed out in chat that's a good point the downside of this is that you can't hot reload using this this style of way of doing things well I suppose you can just pass the old state into the new thing but >> I guess you can't reload this whole C file yet cuz it's >> because you have to be passing yeah has that >> global Yeah.
>> Yeah.
>> Yes. Okay. We have all the other state.
I don't think we should spend too much time.
>> And now we have helper and helper functions.
>> Hey, camera basis from yaw.
>> Yeah. See, this is the kind of thing where you can just be like make Oh, so good. That's why you're the host.
Um, I call it make uh camera from world or make world from camera cuz again like I don't know which one this is and so I just kind of have to hope um >> cam >> so from world like this >> or yeah or world from camera like I would call like make >> but it should be one of those two. So, and then all of your matrix functions can just be that and then you're never confused.
So, yeah, here we have this this this this issue with like losing the understanding in what's basically.
>> Also, this one is a little skeptic cuz you got yaw right and forward, but I guess that's probably the useful thing for the game. So, that's okay. You know if that's um >> okay quaterturnian from axis angle >> yeah classic expected >> turnian is zero is a sketchy function to have uh so I'd probably audit where that is but I guess maybe if it's like it might mean that's uninitialized quitterian or something it's that's okay but I might rename it to like well yeah anyway cuz you never want to check against zero with floats. But >> uhoh. Uhoh. He's going to be pissed.
Look at him. Look at him. He's going to be furious.
>> Not Not thrilled. Not thrilled about that. We'll have to >> This is similar to here is zero. So I think this is a bit of a logic mistake.
>> Uh >> questionable. Um, I don't I mean it depends on what zero quitterian means, but I'd rather it not mean anything. Um, also quitterian subtract.
What does quturnian subtract mean? And this is a rotation.
>> Is that like the angle between two?
Oh god. Quian subtract between two angles. Okay. I thought it was doing Oh, that's okay. Oh, this is real.
>> What? What is quturnian subtract >> million subtract?
>> What?
>> What?
>> Uh-oh.
>> That's not logic. That's not logic.
>> What is quitterian subtract? That's not a thing you do. What does that do?
>> So this is >> quitterian multiply by a scaler.
>> This is uhoh.
>> So illegal.
>> What are we doing here?
>> Not defined. Quitterian ad is is also not a thing. Um >> not real quaterians made up math.
>> I mean you can do that but I don't I actually don't know what it does. Um scalar multiply.
So maybe maybe uh maybe you should tell why.
>> I mean I'm not an expert on quitterians.
So all all I know is that the operations you ought to have unless you're an expert is like multiply and conjugate which is like the inverse or really you should have in inverse which is the conjugate divided by the scale or something I forget exactly but um really you probably just want quitterian like lurp quitterian angle between make quitterian from axis angle and kind of treat generally speaking quitterians is like black boxes encoding rotations.
Um, if you start getting into like raw quitterian math, you better really know what you're trying to accomplish here.
Um, which is incredibly rare in game math, especially like hobby game math. Um it's like quaternian's definition involves imaginary numbers and uh if you like you're not supposed to treat w as a as a real thing like it's not the coordinate system. It's not like 4D coordinate system. So let's go and the these operations are pretty much undefined as far as I know as far as I remember.
>> Yeah. I mean the other thing is >> if you add those two you don't get anything useful like >> yeah because >> whatever it was like for >> right like yeah exactly like quatern I don't know what the the correct math language is but they they form a specific kind of group I believe right and then you want to make sure that they remain normalized probably you can do a non-normalized quturnians but like for scale but you got to make sure you do it carefully There is a great video of three blue one brown.
>> Yeah.
>> With the visualizations of like hyper planes and how they change. So like not every not every combination of these numbers will be valid. As Anton mentioned you need to keep them normalized. So it's not like if you add two together like this is basically vector adding but it has nothing to do with quitterians.
>> Yeah. Yeah. So I mean I I think personally quitterians should be their own type. I think using vec 4 as a quitterian placeholder leads to mistakes more often than not. Although I kind of also get it because in graphics typically like in shader programs it used to be common to use ve for quitterians and shaders because blah blah blah but um yeah I think it's a bad idea. So I would have quitterian as its own type for this reason. So that way you can have separate math functions for your vectors and your separate math functions for your quitterians.
This is not isolated occurrence.
>> So it looks like it's doing a lot of >> animation. Yeah. So it's doing reormalization after the add. Okay. So it's look scaler multip. Yeah. Okay. So this is doing the equivalent what's called like an end lurp. So I would um I would re uh I'd repackage this whole thing. Quitternian normalized quaternian add quitter scam.
That whole thing if I if I'm not mistaken is what's called an nlurp as opposed to an slurp or slurp. And nlurp is this idea that you just take two quitterians and you just lurp between them and then you renormalize.
And it actually produces pretty nice interpolation. So, a lot of people knock and they think like slurp is better, but nlurp has some nice animation qualities because it's got like a baked in easing effect into it. So, I actually like endl scaler multiply.
Uh, I think it's a little too raw for me for my taste. I would just make an quitterian and llurp function and then it's clearly documented what it's doing.
Um, and then a quitterian slurp. There you go.
>> This would be an LAR.
>> Yeah, exactly. Is that from Claude?
>> No, I just wrote it down from memory.
>> Oh, damn.
>> And this slurp.
>> So, yeah, probably best to be have this isolated. But I don't know whether this will this is what we'll get from these.
It doesn't >> Well, you've got param look. So I'm just like I'm using my pattern recognition.
So you got PAM param is probably the parameterization of time cuz look you got frame index + 1 / animation time. So that's probably forming something like a 0 to1 scaler. And then I'm seeing the canonical lurp form which is like a * 1 minus p. And if you scroll to the right I suspect there's going to be scaler multiplied by param. There it is. So that's your front that's your inline lurp. It's >> lurp between a and b is a * 1 - t + b * t. So that whole thing is a lurp and then it's wrapped with quitterian normalize which is probably just a normalize. And so then really it's just lurp the quitterians normalize which is nlurp. Oh wow. Okay. Yeah. It's my reverse compiler. It's like nice. That's a Yeah.
And LAR got it.
>> Um, perfect.
Quitian dot also. I think you have Well, anyway. Yeah, that's probably quaternian dot. You have to be a little bit careful because of the double wrap on quitterians as well. But I don't know if I can do that one off the fly to know.
Okay, we need to go back to >> something like 500.
Where were we?
>> We saw the quitterian questionable functions. And so yeah, okay, but that's a that's that's way way uh it's good that this is what happened with the quitterian add and quitian subtract because initially I was terrified but yeah but now like okay it makes sense. They just need it as part of a lur.
>> Yeah, it just uh uh more verbose and not uh extracted as a function.
>> Yeah. So with quitterian dot I I my brain says we have to check whenever we use dot and compare things we we should consider whether it's the absolute value because there's some double cover stuff going on. And then quitterian conjugate scares me slightly because um conjugate and inverse are usually not what you want or sorry conjugate and negate you probably want inverse which is conjugate divided by the scale of the quturnian.
Um, and you don't exactly want to normalize cuz when you compose a bunch of Quitterians, you want there's like a numerical stability that's famous in Unity. If you do a bunch of Quitterian math, at least in the old Unity, they used to slowly get denormalized and like grow in size.
And so everybody had to keep reormalizing them all the damn time. But it was all coming from the fact that the inverse was defined as the conjugate rather than the conjugate divided by the length.
Okay. So, watch out. Probably use inverse instead of conjugate, but a lot of like tutorial content talks about conjugate.
Um, and what why why is normalize doing that?
Length squared. Oh, I see. So, it's just doing >> length squared.
>> So, it's just basically saying don't normalize. Yeah.
>> Yeah. So a better form of this is um just yeah no I mean that's fine that so it basically returns identity. Yeah, if it's if it's too small to normalize, that's fine. We'll live with that.
Cross product. Sure. Okay. Now we enter from quadrian. We enter vectors.
Rotate by quitterian.
I guess I guess it's correct. I don't have compiler in my eyes. This is the part this is the part that we >> there's lots of different versions of rotate by quitteria as well and but there is a cute one where it's just the quitterian multiply.
So there's a version where you can like you have the quitterian multiply function and the the one that I like because it's cute. I don't even know if it's faster. um you can pack a vector into a quitterian and then just pretend it's a quitterian and then multiply it and then that is the vector times quitterian multiply.
So I don't know what that formulation is and I'm reading the chat it's like yeah you're probably right that it's probably a division by square length squared or something. Yeah, I'm probably wrong about that. I don't I just remember there's some length involved that if you don't take into account the length you slowly get drift over time.
>> By the way, on a unrelated note because it's C, you need to first define a function that you're going to use below, right?
>> So all of this needs to be in a specific order >> of first happening there and then we do cross product >> so that we can do the cross productd here, right? So like >> you don't have to do it that way though because you can forward declare all the functions. So just on a kind of tidiness level this is the stuff that I would put into types. I would rip out all of the actual names of the functions. I would put them into one block of declarations.
So then it's easy to read kind of what's in your math library. And then after the declarations I would actually do all the implementations of the functions and you keep them in the header so it's in line so it's fast for math. So that would be like how I'd structure the vector library.
Math helper functions and chords to norm.
>> I don't know about that one.
>> To normal to to float to float >> float float.
>> Yeah, >> this stuff's hard to name.
>> Norm int.
>> Yeah. Floor >> with the floor. with the floor. So this is like implicitly saying round to nearest cords within level bounds. This is by the way like when I was doing this type of code for some whatever experiments or games or like things that happen on 2D squares.
There's so many little conversions of like is this on the tile like in the center of the tile or is this on the edge or is it in the corner and >> to the point where I invented up like a new coordinate system. So like I didn't I have if you have like even 3D things that are happening on the grid like here uh I had the normal like uh MVP free coordinate systems but I also had >> system on the tile directly right like the center of the tile and then the corner of the tile >> and I could move between those like as coordinate systems because like I needed to have this defined clearly where am I that >> I think that's a very good idea. I don't know if I would do it with a coordinate system, but I mean that's for 3D that that does make sense. And that way like you can use suffixes to know which one's which cuz you don't want to mess those up in graphics. These are like the half pixel errors that you get. Like famously you UV coordinates for example are meant to be corners of well UV boxes are corners and then UV samples like S fragments or centers of pixel and if you mess that up then you get all sorts of really subtle artifacts. So yeah, I think I usually have a function which is like convert from centers to corners or corners to centers and then I suffix my things with corners or centers um similar to the spaces and then try not to mess that up especially in code that's really careful there.
So here I'm assuming you need to kind of remember this when within this code like >> yeah and it's using the level dimensions that are global. I don't love that but we'll roll with it.
>> This one. Yeah. So it's basically saying there's a level and then we're just going to check it. But because in C you don't you don't this is another place where I like C++. This is a case where objects are handy. It's like I have a level object. Is it level cord contains or whatever. That's like nice. It's nicer than having a global cuz now you know if your level dims are not set right. It's like uh it's not clear that you have you should have set the level dims or maybe you're checking about a different level and you accidentally I don't know. So you kind of want to pass the level in but then that becomes cumbersome. So okay equality >> negation >> is zero.
>> Yeah.
>> Int is zero. This is this is float zero.
So this is >> yeah. So a better format for this is is returning a bool three. So if you look at how glance that ends up being better. So you return a vector. So when you compare for for all of your comparisons, whether it's zero or equals or less than or whatever for your vectors, you return a bool of that same uh dimension. So it's like a vector 3, you return a bool three. And then you can define things like uh there's an all operator which just basically says x and y and z. And so the syntax ends up being if all vector equals vector, it's let you talk about the components. Um, yeah. So it's like if all vec A equals veg B.
Yeah.
So that for example would say if all the components of vec A are equal to vec B and then you get zero for free because you just say ve a equals vec zero.
Um but then the other one you have is any which means uh that's a common one like if any of the components are equal to zero you do some logic. So that covers a lot of your cases without having to write like all these permutations. Um, and any of Yeah.
Yeah. Yeah. Yeah. I think so. Yeah.
Perfect.
Stolen. It was stolen.
Um, but you you know you mentioned this kind of fiddly code on grids and it's pretty typical that you have this kind of thing of like you're checking something inside bounds and so the code becomes if position greater than or like if all position greater than or equal zero and all position less than or equal dimensions >> and then that types out all of the four checks that you have to do along here. So that's kind of nice.
>> Like add and subtract subtract.
>> Yeah. Yeah.
>> Victory amps a >> multiply.
>> Put it into vehicle it >> inner product aka dotproduct.
But if you're going to call it inner product then you should call cross productd outer product.
Be consistent. Damn. Damn. What a review comment, man.
>> But I had no idea that that product's in a product.
>> Yeah. I always >> That's why like John Blow used to have a column called the inner product or something on on game uh Gamma Sutra magazine.
>> It was all math.
>> I didn't know.
>> Vic length.
Vic length. But I can see ve length squared >> sign length.
>> I would I would I would probably suspect if we're doing this already like we're making a library >> like you can have this.
>> Yeah. Make that library. Yeah. You need that squared >> and then you can repackage it >> because >> this is the kind of code that Claude can probably generate but I'd be scared. I'm like equally scared of writing it myself and generating it >> like but if you have enough tests then I suppose it's all fine. I don't know. I written like I used I had my own math library like this and after probably eight or nine projects and years and years of using it. I discovered my dot product was actually left-handed instead or my cross product was left-handed instead of right-handed and just like never came up. And then I kept chasing this code. I'm like what is happening?
Why is it reversed? And then I was like, it's the cross. And then I found the bug in my cross product. So it's real. But I don't regret it. I regret nothing.
>> But this is always with these like base libraries for stuff >> and it's always and it it really is painful to discover this over time.
>> Yeah.
>> Just today I like did in like code at work. I I spent like 3 hours understanding why there's a crash at runtime and like everything should be fine. there was this like templated service registry where where you have multiple inheritance it didn't work but if I had single inheritance it worked and I found out after hours that there was a reinterpret cast instead of dynamic cast >> so if you put as a first base class it worked but if you put it as a second one and then you ask for this type it would give you but the offsets were So if you want to access the function you have a runtime error. It was like this is like this base level because like we made this super generic thing >> that is supposed to handle all the cases >> you know and then you just >> you forget about some because C++ is not >> a normal language. No, >> B for real programmers >> uh signed length.
>> This is like akin to my remember that function we found in in my code which was like reduce by or whatever and we spent like 20 minutes figuring out what by meant I think this has that flavor >> like cuz what is assigned length? That's not a standard concept but >> um >> ve length it's a float. Okay. And then it's like if it's equal to the apps.
>> Whoa. What >> I guess I guess it would be easier to see where it's used. I guess it's like >> I guess sometimes it might be useful to have already like you're doing something in a direction, right? and you need a length and then if you compute the length and it's always positive now you need to be like okay if it was this direction then I need to minus one it and like blah blah blah.
>> Yeah. I mean yeah but I get the vibe but three abs.
So it's basically saying if it's in the if it's in the positive quadrant then it's length >> but in any other quadrant it's negative length.
>> Oh that's that's not uh that's not mirrored. No >> it's not mirrored. It's just one quadrant or the other three.
>> That's most likely going to be a bug.
But it wasn't used in this other the fourth quadrant. I forgot.
>> This is this is my my bad. I think it's used in quadrant like two and four or whatever like >> the quadrants.
>> Quadrant four is waiting.
>> Okay.
>> All right.
>> Normalize.
>> Okay. Normalize >> hatamard here.
>> Oh. So it's not outer like went full hatamard but hatomar product. Oh no no no. Yeah. So yeah this is the hatomar product. Yeah. Sorry. So yeah. Yeah. So you got to do the outer product for your cross product.
>> What can you explain this?
>> Hadamard is component-wise multiplication aka the the standard thing. But if you want to go full math style hatamart is just you just multiply the things.
It's almost never used because I don't think I don't it's for scaling matrix.
It's multiplied two vectors component-wise or two matrices component-wise.
>> And when is it being used? You mentioned skin skinning.
>> Uh probably it's you can like for color scaling or for tinting. Color tinting.
>> This tint color tinting. That's right.
Multiplying. Yeah. Yeah. Yeah.
>> Yeah. Okay.
>> But you can do it on matrices, too.
That's why it's got a math name.
>> Ah.
>> So the the Let me see if I can get this right. So the the hat had product is the standard multiply of matrices by components almost never used in graphics never as far as I know. And then the outer product the inner product is the standard matrix matrix multiply I think. And then the outer product I forget what that does but maybe someone in chat knows but basically all these are defined for matrices as well.
>> Okay.
Okay. We go for the sake of time like we go. Yeah.
>> How where's your when's your deadline?
>> Got about 40 minutes.
>> Mhm.
>> Speed up. We got to speed up. Uh quartz the buffer index type.
>> Yeah.
>> Quartz the buffer index direction.
Uh okay. Set tile type.
>> Yeah. Let's just move past the helpers.
I think I think we got the gist for it.
>> Okay. Then we need this. We need Claude's ranking >> of helpers.
All the mathy helpers.
Claude estimate chat. You got to vote as well. Drop a number of hours that you expect Claude and you prompting Claude to take generating the function functions that we've seen the helpers for quotians vectors pretty much math library and signed length >> and signed length that one is going to be. So I my suspicion is it's like one hour for everything, you know, cuz that's our minimum, but then kind of like an extra 8 hours to do the signed length and other non-standard >> to force to force Clark to do something weird for a quarter in one >> good clone. GLM. Yeah, there you go.
>> Okay. My take is is actually one hour.
>> I think it's a barebones thing. Like everybody in the C++ world, everybody at some point like >> I'm going to do my m my vector map library.
>> So like there has to be like thousands of examples for this.
>> Yeah.
>> Yeah. 1 hour above buggy possible.
So now I'm going to look up here win main.
And here we go. This >> I don't know any I don't know very much about win code.
>> I'm not going to be >> this is Casey introduces in the handmade hero >> which I'm assuming this is why it's here. Not not like this is the the proper entry point on Windows.
>> Yeah.
>> But you can use main from the standard library and use it.
>> Yeah.
>> Every time I read this code and I do it and then it just exits my brain >> like >> I think that's that's what's was supposed to do like the the design design is for you to do it. So I'll just this the kind if someone's handing me this review I just be like LGTM man like let's we'll find the bugs later one can never know if there's bugs in this code it's impossible >> here is here is one thing that I wanted to mention before we go to game initialize right >> query performance counter >> do you want to have a bit talking about that >> uh that's what I use so is it bad No, it's just that as far as your ability as a programmer to get readings from the machine what happened and how much time it took, right? There's no like clock meaning like clock we wall clock we have on the on the wall like you you have a CPU based counters and one very basic thing is a RDTSC assembly instruction to read >> RDTSC to read wall clock time. That's like the real wall clock time, right? Or is it Or is it the uh >> It's in the cycles.
>> Yeah.
>> And it What do you mean it's a wall clock?
>> I don't know enough about it, but you tell me. I thought RDTSC was like the internal set clock of um like Well, any go on and then I'll >> The tricky part is that this can be different for different coursees because it's not shared, right? So this is a tricky thing to use because you're you can have inconsistent readings >> and this is why a better way to measure anything is to do query performance counter which is the unified one for all the cores if you have you have in CPU right >> yeah if you want time time relative to >> yeah but that one is not in like actual you know system time or whatever >> and here there's a query performance frequency where you use to actually measure me the frequency of your computer because you don't want to hardcode the CPU and clock rate of your CPU.
>> So you just measure it for like 100 milliseconds or something and you get an estimate and then you use this as an estimate of frequency and then when you have timing.
>> Yeah, let's get to the game, man. Claude can review this part.
>> To review game code, not >> game initialize. Uh >> yeah, there we go. Oh yeah, there we go.
>> God.
So now now my like vim bindings are just messing with me.
Ah okay.
Serious serious.
>> There we go.
>> Here. Okay.
>> Okay.
>> Here we go.
>> We go. You need undo buffer.
>> Okay.
>> Recalate the buck start chords. Why not?
Initialize state. Initialize state.
All right. Initialize state zero. World zero.
This was a little bit confusing.
Read over world zero's word state from file on startup. So it's kept in memory.
>> Used on restart.
>> So it just basically kept keeps it >> it copies it to or world zero. So then if you ever need to reset it, you just slam that memory back in. All right. So, it saves it all. Yeah. Okay.
>> And then game initialize state for the actual level you're in.
>> Yeah.
>> I like it. Let's go.
>> Redraw is related to to the thing. So, we go.
>> Yeah. Yeah.
>> Okay. Pack is the backpack. So, it's basically your >> two entities, right?
>> Okay.
>> And we pretty much initialize things with copying me copy >> and we put the state uh we have the double buffering of state.
>> Yeah, >> that was that was this should be much more like hey this is a huge reveal of this stream. I should have played it more like hey the dreams like double buff of the state what but that's that's that's the intention as far as I can >> but that's probably for the interpolation for the animation right >> this I don't know actually >> but the you generally put things in the in the world state and then you copy over the >> copy over the to the to the to next frame.
So you have >> here we initialize the world state.
>> Yeah. I So for me I of this is one place where I like C++ because I often not often but often enough I I make mistakes in forgetting size of or mis mistyping one of these things. So, I try to structure it in a way where I don't have to type size of and I I like the built-in equals operator in C for this kind of stuff that just sort of handles it. It's easier to read. Um, but you know, >> is this it is what it is.
>> Is this Windows 8?
>> Flo.
No, that should be stdiodio.
>> Okay.
>> Yeah, it's all right. It's all right.
>> Spooked me with the upper case.
>> Yeah.
>> No.
>> RB+.
>> So, we load the level, the binary representation of the level.
>> We close the file immediately. We're super >> job done. Clean it.
>> We initialize things to zero. So this just straight loads the file like So this doesn't have any backwards compatibility which I guess is a little bit unfortunate, right?
>> What do you mean?
>> Or load buffer in.
Oh no, no, sorry. I thought that was from the for some reason I thought that was the um the file load. I guess we we can see the file loading a different time.
Um >> Oh, there's our four macro. There we go.
>> Yeah.
>> Okay. Max entity instance count.
>> Yeah.
>> We do actually have couple of divines here.
>> Yeah. Just don't use them.
>> Why do I go here? Why this like they don't extended.
Ah, okay. Game initialize state.
>> Yes. Let's go.
So we initialize initialize all the entities now to minus one >> that's the ID I yeah I would uh suggest using a define there for like null ID or no ID or some version thereof because you might find yourself wanting to switch that to something other than negative 1 later and it'll just be a basically a nightmare to to try to change it cuz you can't search for negative like negative one's everywhere.
So I think um I'm okay with negative one but I would want it to be named in case you know for example you want to start making things zero for for um for null or nil or whatever that would be a change that'd be really hard to make here whereas semantically what you're trying to say is okay initialize it to something that's invalid.
Okay.
Um here we have initialization of the board.
>> Yeah, >> we have this huge buffer contents.
>> Yeah, >> of the buffer.
>> And then we want to pack the memory of the tiles, right?
We go through the We want to We have the huge buffer.
>> Mhm.
>> For the level.
>> Yeah.
>> We go through all the dimensions and we fill out the type of the tiles to match what we've loaded.
>> I see. So the tile buffer is basically a uh dims by dims x by dim y by dimz. But why is there two?
>> Why is there two?
>> Uh there was two.
>> There was some note on >> the two all about is that like previous and next?
>> Uh I don't remember. There was a next >> there was a comment somewhere where >> I don't like it.
>> I don't like it.
>> World state >> but for two bytes per tile.
>> World state. Yeah.
>> Two bytes info per tile.
I think this is a excessive e excessive bitteness. I would just make it a strruct make a strct tile, you know, make it make it a 2D array.
Don't don't linear pack it. You're just causing yourself headaches, I think, cuz it's fixed size anyway. So, just make it I guess in this way you can >> 3D array.
>> Yeah, 3D array. I guess you this way you can change the sizes and still be fixed.
So, I guess that has some benefit.
>> Oh, Spike mentioned one bite is for file type, one is for the direction.
But if you want to add more bites, like I want to add like broken tile and colored tile and slippery tile and it's like h it's like true false found. Remember that meme?
>> True, false, found, not found.
>> Yeah. Yeah. Yeah. Yeah. Look it up.
>> Like you add more states to the bull.
>> There there's like Yeah. This is like an ancient article where like someone discovers this enum which is like enum whatever and the values are true false and file not found. It's like a bool enum bool like in C and the values are true false file not found.
I remember countless discussions at work. Uh what does it mean to have optional of pool?
optional pool >> like like what what is what what what you wanted to represent with the null that uh >> yeah no I think I would if it was me I would just make tiles I kind of I I know where this is coming from though cuz I' like I've written these sorts of tile things and then you're like oh I'm going to pack everything into eight bits and then you're like oh it's kind of annoying I'm going to make two bytes and it's like you kind of either I think the one way you go is that you say Okay, there's just going to be generic data.
Maybe it's an int or or like literally a bite array, but you still make that a tile and then you write a function which is like pack it and then you pack the bits and if you're really going to keep it tight, you you make it into a single function and you pack all the stuff or you just make it a strct and you set the fields. Um, but the in between world of like I've got three bytes and by three is this and doing that logic in line tends to kind of cause more bugs than it's worth I think.
Okay, moving on.
Now we're in the like speed up mode.
Okay, we need to be super quick as if we're like >> high level high level LLM. Okay.
>> Yeah, high level LM.
>> Um, >> high quality. Um, okay. This is still everything initialization, right? Load win blood pass locked info pass load reset block pass camera main waiting alt waiting ah because we have different cameras right >> al from alternative I'm guessing >> mhm >> okay and the world state equals next world state we flipped the world okay >> I think we can go to game frame let's do it I That's going to be the meat of it, right?
>> Frame game logic.
>> Delta time like we thought. Delta time.
Oh, I thought it might be time.
>> If delta time is bigger than 0.1, delta time is 0.1. There's your frame rate limiter, man. Oh, no. I guess not. It's the other way. It's like if you want to go much farther, it's like no, you can't. 100 milliseconds is all you can do.
Physics accumulator delta time. Okay, >> so this is for stable a stable delta time >> fix time.
>> I don't understand this >> actually. I don't know. It sounds like it's probably going to get passed in as a variable, but we'll see.
>> Yeah, if it's checking how big it is, then it's basically saying like what this is for is I suspect on the outer loop it's saying, okay, what's the time of the first frame? What's the time of the next frame? Subtract them. That's delta time. But then if you like alt tab out of a window and then come back a minute later, the delta time is going to be like a minute. And if you attempt to simulate that in physics, it's just going to be bananas. And so it's basically saying, "Oh, your delta time's huge. Just advance by a little bit." So it's preventing these giant steps of delta time.
Oh, branchless.
Branchless, >> bro.
Save some save the prediction.
>> I think this is this is for me like >> you like that.
>> Maybe maybe it depends on maybe it's a preference. Maybe I don't know if it's really readability.
>> You know how to write quitterians from scratch. So you're >> but I did but I almost did this. So maybe maybe actually it's better.
>> Okay. And we have physics accumulator.
And so we have like a separate one for physics like we don't base off for delta time but this means we have a variable delta time for physics.
>> Yeah.
>> So that's yolo like you have you need to have a proper integrator and >> well I'm I'm hoping that we're just interpolating between integer states which I'm guessing is what we do.
>> We probably wait for some amount.
>> Yeah >> something. So, we have accumulator, but then we have time step that is different. Default physics time stamp.
Okay. Okay. I'm not going to skip past this. So, we're going to go slowly.
>> It's probably fine.
>> Troll command camp.
>> LGTM.
>> Next world state player. I'm Why are we taking from next world, not the current world?
>> Cuz I that's who we're going to write to probably.
But this is like sketchy. I would have I would call it like player next or something or pack next cuz it would be easy to I think make a mistake there cuz you don't want to read from player at this point. Camera input always at 60 Hz.
Never drop frames.
Don't make no mistakes.
>> We make no mistakes. No drop frames.
Solid 60. Yeah. Edit state. Edit mode.
No mode.
YOLO >> your camera sensitivity. So this is to to control the camera.
>> Camera control. Yeah.
>> Mouse position assuming in screen coordinates. I'm guessing >> that's fine.
>> Camera pitch.
Okay. editor state if it's no mode and if it's not select right which means it's not mode or select right okay all right camera basis for basis camera basis okay this is camera code I'm skipping past this >> there you god control >> loop yeah looks good >> handle writing once Once per present frame select right.
What are these modes?
What is editor mode?
>> No mode. Place like I guess maybe it's I don't know actually.
We don't know.
We'll find out.
Okay, I'm coming back. Maybe it's like add blocks, remove blocks kind of thing or select blocks. It's probably something of that nature.
All right, close. And this one camera moves. This is camera. This is select.
Okay. Writing to field. Get entity from ID. Selected ID. Writing field. Next level. Take input. Enter. Press this frame.
So here's okay. Enter. Press enter. It's like you pressed and enter. Now we want to execute this part. Okay.
So here.
Yeah. I feel like it's a a little bit mixed in like the the input logic is mixed in with the >> Yeah, but it says that. So it's it says it says this is a bit messy. So what are you what are you complaining about?
Look, there's a comment.
It says what it is. Like, you didn't come here for some clean code. This is a little bit messy code.
>> At some point, probably in the future, like if you had going to have more than one input method, like more than keyboard and mouse, you would need to abstract it anyway into actions, right?
be like you would have one place where you define what what are the actions that you want to do and then >> what will contribute to this action and then it's a little bit easier if it's even only for the keyboard you already have this like mentality of like okay what is this action that I'm performing right here it's a bit press this frame or like you have shift entered or whatever this one I don't understand at all >> I think it's probably just trying to slam that change in immediately or something cuz you changed some things and then I don't know I'd have to read more to to understand. Okay. So this is like if you press enter but if you don't then doesn't happen mode toggle select right we change gameplay mode change place break >> select >> uh down physics >> modes are probably these like are you playing >> are you clicking in the editor and >> no mode's probably play mode >> no mode is gameplay mode change >> yeah It's game mode. Yeah, game mode cuz it's no no editor mode and lack of editing means it's a game >> break is not it's like place slash break not both place break.
>> Yeah. So it's like left click place right click break probably or like add remove mode or something.
>> And this is select mode. Damn. Nice.
>> Speed up slow down physics tick. Okay.
Now, now we're going to like we're almost at the end and now we're going to enter like the actual discussion >> and like now it's going to be like oh actually it's accumulating times like oh this is not deterministic.
>> I think we have to I think we have to skip this. It's too good. It's too hard.
We're just gonna have to like spin up an agent and be like, "Claude, please check for me if this is correctly handling time steps."
Yeah, we're we're not going to go through this, are we? Like we're not I don't think we'll make it through all the all the details >> because this is this is this is interesting. Physics time step divided by two physics time step times two if you comma press. So I'm assuming this is like slow down speeds up speed.
>> It literally there's a comment and I just discovered it.
>> Yeah.
>> Yeah.
>> Physics accumulator is more physics time step.
>> Okay. So this is a tick like this is what happens.
>> Like >> we map the new world state to the next world state. I think like should it be the opposite?
I feel like we always write to the next world state and then at some point we're like >> we flip it back. I think the idea is that you're going to write to the next one. So you initialize the next with the current update it and then flip it and then you have the previous to do your interpolation.
So it's not quite dream style because in dream style you you you save the copy by writing directly to the next state. But this is sort of like the the simpler version.
It doesn't matter because we have 64 entities, right? Like our max entity count is 64.
So that's why I like to read the strcts because then it like colors my perception of how to judge the rest of the code.
>> But isn't isn't this like a starting value and I will doing development and then you realize actually I would like to like have an order of magnitude more.
>> I guess that's what happened to the soabon John's game, right? Like we were going to have one level at a time and then there's an overworld. So now we have 60,000 entities >> or whatever, right?
>> Okay.
>> Yeah.
>> Then you just got to roll up your sleeves. I think we need to start wrapping up.
>> Unfortunately, we couldn't go through the entire frame, but we've seen a lot and I think we can go into sort of uh closing statements.
>> Okay. Anton, from what you seen >> on this code, what would you say like are there any large scale adaptations that you would do?
>> I changes like big changes I >> I think generally um uh I I I would start by kind of doing like a Casey style compaction of common functionality that has shown up. So that's like a pretty mechanical task to like factor out some functions and that will make make it a bit easier to read through and you might find some bugs along the way. I I don't know if there are any but that's a good um >> you're saying this about like quotian LAR situation or >> all the math bits can be >> you suspect the game logic as well. No, I think game logic is really hard to compact honestly, but if you can pull it off, like I guess it depends on what it depends on what the the next problem is, right? So like if the question was, hey, does this work? I'm like, I don't know. Like you'd have to read it and figure it out. So there's no real sense in code reviewing it like that because um you know, you can't just look at the code and figure out if it's going to run or not. So you have to kind of pick a goal, right? So if the goal was to um add more logic or add more items, I would probably do some rationalization of how the current items work. Maybe use like more more like a trait based approach as opposed to the enums. I would probably do the thing you said which is try to use um if you can try to use less enums that have like magical negative values and things like that and try to make it so that you avoid those negative or the avoid the invalid cases. So you definitely could could use a little bit of that kind of massaging if you want to add more things because it at least for my brain it's it's at a sort of critical capacity where I feel like every time I'd add something I'd probably add a bug somewhere. That's sort of what I'm feeling. Um, so and and that would also be true for all the copying like there's a lot of inline mem copies which again is fine like you're going but as the code break base grows it's easier to it's better to factor that stuff out I think. Um, I probably I don't I don't know enough about it, but I might consider reformulating the next and current state as a just write to your current state. Like at the beginning of the frame, make a copy of your current state and call it previous state and then just write to your current state and then at the end you have your new current state and then you have your previous state and then you can do your animation relative to that. I don't know if that's how the animation is actually done. I'd have to look at it more. Um, but I think framing it as like next.
Well, I don't know. It depends. Maybe that maybe that's for the undo buffer being applied. So, it's like a command pattern kind of thing where it like applies it and then you get the next state and then maybe undo. Um, for this particular game, um, because the state's minimal, I would re I would probably implement undo as just like a straight up copy of the entire world state. And that might let you simplify your undo code. So if your undo code's giving you trouble, I would just make a straight up buffer of like 64.
>> Really? Like copy everything?
>> Yeah, why not? 64 entities, man.
>> 64 entities.
>> You're hung up on this. Like, but what about the buffer for level? Like it's bigger.
>> It's fine.
>> YOLO.
>> Count your memory and be like, can I allocate 500 megs? Probably, right? Like nobody has less than a gigabyte of RAM.
like you'd have to be hardpressed if you're running on a you're you're on Windows anyway. So it's not like you're running on Raspberry Pi Linux or something. So like just revel in the address space of 64 bits and just allocate a bunch of space. Now if you want infinite undo then you know I'm not sort of knocking it as a technical decision but depends on what you want to do. If you want to learn about undo then great. If you just want undo, copying your entire game state is is a perfectly valid thing, especially when your game state's already a nice clean strct of just stuff. So, that's that's a thing you can do to reduce um some of the complexity.
Uh but yeah, the if the math I I'd clean up the math stuff, but that's not really game important.
You know, if if the game's running, then it's running. Um, but if you start having math problems, I guess it's with all these things like if you start having math problems, probably rather than fixing the math problems, it's better to just take a step back and fix some of the math cleanliness on the whole and see if you can abstract away things like endlite to fixing math bugs because you want to do a little bit of house cleaning and then the bugs will become apparent.
Likewise with the state, if if there's like state bugs, do some house cleaning on the state first and that might illuminate the bugs and then as a byproduct you get cleaner code like in the Casey compression version. Um that's that's sort of what I do. But it it's it runs it ships. That's great. I love it.
All right. Awesome. Thank you, Anon, for joining me for the review. Thank you, Spike, for submitting the code.
Thanks everybody who joined in and tuned in to stay with us and look at the code.
Thank you everybody.
>> Thank you all.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











