 okay what have I forgotten to do you have to put up with me eating at the beginning of this be right back to fill my drink all right let's get this show in the road do you have an idea of what you will be talking about at handmade con yeah I'm part of a panel but Casey didn't disclose that so I'm not sure I should be disclosing that I still don't have a watch count which takes too long to update that so what are we doing right oh yeah cuz I checked that into a different branch yeah that's all fine so we were left this last time as we have these guys following us around sort of falling oh and I press a key they follow but they try to go to where I currently am when I press a key right but it's a little broken because I can get stuck in stuff pretty easily so I thought I'd fix that all right yeah I think that's okay I'm glad you guys like handmade con I kind of I'm a little about it I feel like the density of information is a little low due to lack of preparation it's not for me anyway but I mean I know like in theory it would be in some sense because it's kind of for Casey but since he's often really just asking about stuff he wants to know as opposed to stuff geared for the community it seems like which is fine again so there's all this complexity to how we handle player movement in response to the player controls but you don't actually see the player controls anywhere in here this just comes in with I'm trying to move in this direction and it does what it thinks a player should do to try to move in that direction and sometimes it gets stuck and you have to overcome it and stuff so what I'm thinking is we'll make these guys to try to move to you because since they currently move right through the ground and do some terrible stuff as we can do this we can just have it call the player one it's always on ground wait this doesn't take on ground this is move walkable doesn't take on ground it turns whether you're on ground or not but it assumes you're on ground when you get here so I guess it must be doing something similar yeah I've mentioned this outside the physics it's doing some of the physics outside the physics file the player physics yeah where is it here it is physics blah blah blah blah I don't see an on-ground test yeah it actually does it so if you fall off a thing I think it still lets you control it like if you fall off a cliff and you were falling in mid-air or do a nice parabola but I think it would still let you move freely because it doesn't check that all right plate Z which we're going to discard the internal Z is how we smoothly step up takes a size and takes it all if that returns true then we're on the ground probably the player should be doing basically the same thing if you fall off a cliff you maybe you have a really limited control but now this should keep the guys from getting stuck in the ground so that goes half of our the AI problem the other half the AI problem is that their start point isn't always valid because they can be standing here you know they're that wide but their center point is over this block and so it it tries to evaluate them as if their center point as if they were fully contained in this block and they say you don't fit fully contained in this block you can't stand there you can only stand out here so it doesn't know what to do so where we do that just in world a path find so what we do have to do here is try a couple different starting positions what we really want to do is probe we can just do this it's kind of cheat a tiny bit but maybe not too much stand break doesn't do it we need to break out to go to and then we get to here it failed so then it's zero now I can move all this inside here does that cover every possibility no that doesn't cover every possibly if your center point is at point one point one then you extend out to the side so what we actually need to do here is we need the size the bounding box basically of all the spots it's in and try all those that's actually what we want to do I can't imagine that actually works but try it most of them are still stuck it's not pants path finding to me they're all stuck now nope they're much stucker than they used to be all right see if we're ever getting to here nope we're never getting here so this is failing all right so let's look at oh I see one bug that's probably the only bug that matters cut base bug so not the second on work but that was certainly a bug all but one of them all but one of them so why is this guy stuck it looks like he's in a reasonable spot oh and we hit a bug in Pathfinder or no that's the path follower I believe that's our position 29 pathline 30 it's supposed to always trigger this okay that happens if you get out of position that's negative 28 negative 31 they ran down negative 29 32 that was our pause negative 29 negative 32 they should have been equal like to hit this assert we have to have hit this increment so we had to have been here then this test should have been true 29 is 30 minus 1 and then this should test should have been true unless if the Z was wrong so it was entering the square and it had to fall down and it hadn't fell down yet so it just has to get into the same well it could jump down from higher actually yeah we really don't handle that very well well if you made it to the last one and your x and y is right we're just gonna say you're there because if you're up higher on a bridge or down in a pit so maybe that fixes that but it doesn't explain the guy getting stuck so let's see how long it takes us to get a guy who's stuck okay this guy's not stuck right there if you didn't move but that might be because I was in midair no okay he's gonna stuck alright so now we can look at why he's stuck he's again here no he's not why is he not getting to here why did I get to here oh I've got to make it less than equal all going all right address that maybe they do pop up when they step up because I had them not do the interpolated step up which is intentional okay so now the thing is that they're still moving very strictly on diagonals and I try to fix that but I'm not sure it's worth fixing or at least not at this point it's not so bad that they strictly move on diagonals it's up on there in a bunch I'm okay with that I can't have fun to me oh because I'm yeah you can see how they all line on to that row all right something for me oh a bunch of them couldn't do it why can't they do it why can't they find me can they find me if I'm over here yep I can't I wonder why they couldn't find me up here they can't find me here they can't find me here here here yeah interesting they can't find me once I step up there I know what that is so I should I debug that unfortunately like I have too many of these guys so I have to do something different to debug that so I debug that or should I say enough pathfinding and move on to something else in C somebody's asking how assert works in C when you compile and debug there's an assert macro that's defined to test the assertion and break and print an error or whatever and when you compile non-debug mode the macro is replaced with a different macro that does nothing a pre-processor macro using pound to find it's platform-specific how exactly it's implemented and you can make your own though pretty easily all right nobody had an opinion on that so I guess I'll debug it all right so how do you debug a pathfinding problem like that can't seem to pass find to a specific place but only for some of those guys well I'm gonna seem that the sum of those guys is based on where they were warp nuts UI scan code so what we're gonna do bulls before how big were they turn pathfinding where does this compute it's player behavior AI pathfinding where's AI pathfinding not this file make an AI file to put an object where did it put that there's past behavior 1 1 3 okay let's make that match then do is say base dot x equal yeah the twitch notifications is flaky I've asked in the past if anybody has any idea what a better way to do notifications is then Twitter it's obviously most people aren't watching Twitter at the time obviously I could set up a mailing list but I would like something more automated it seems like other people would have this problem and some site ought to just have the do your twitch notifications click here when you are streaming on twitch and we'll send out the mail but I haven't found some all right so that'll gather the data now we need to display the data we're already in the right file we already have this thing to render this stuff for some reason it's not showing anything I've mentioned that before I'm not sure why it stopped showing anything you ought to show the last path finds data I think and draw this blue yes twitch fixing their stuff is obviously the right way okay this is a little slow now so I'm rendering all these dots with a very inefficient path because cubes blow up pretty high so we search okay it's claiming I can path line from a lot of these places that are in mid-air which is pretty clearly bogus and for those of you who are minecraft aficionados this is basically sky grid oh it does I didn't have it selective that's why if can't have okay shut the right order I should have I probably should have just cannot class the order here but J.I.K. yeah they're all zero it's not rendering anything now frame right this back all right that's oh nobody can pathline to me that doesn't seem right I probably have a bug nobody can pathfind nobody can pathfind it's not drawing them somewhere else position negative three 3677 that seems reasonable start will be unreasonable which is only buried underground a lot of the time you have to step through a bunch of it before it gets up to the the right level I would this not work a lot of these don't feel here but some of them should get to here why can you not stand at the desk why can you not stand here why it's the desk not standable 13177 13177 why is this not standable any ground did not return true why did any ground not return true so I know that is not a oh because there's stuff overhead let's just gonna make it hard to understand this let's let's get out of here where I had stuff above me obviously it's the data let's go to this area any ground should the ground should be there everywhere the ground is 75 that's off by two why is that off by two it's a head height problem I forgot to subtract out the head height again I keep thinking that these things are stored at the location of their feet and that stored at the location of their eyes that's I should change that because that's just gonna keep burning me because it's wrong to store it at the location of their eyes this I got to put this so search to here bunch of things that can get to here nobody can go up to here oh because I changed the search to not search down okay I drew this off-center fix that it looks like they're wound backwards too but you can't know my tell sorry am I chewing with my mouth open it's difficult when you're talking at the same time I was raised to not do it but I do it anyway how was that wrong why would that put them in the corners I don't understand why would that put things in the corners okay so I don't because they're still integers fix the bonding on all of them all right so it takes a little while the compute tells me which places can pathfind to where I just did that and it's about what you'd expect right every everywhere within the probed region can do it don't see any gaps here looks like everyone can do it be up here you can be up there all looks pretty reasonable all right so now if I get up on here do it yep okay now it's centered around where I am now and I work and still do it and now if I stand up on here this is where I've said in the problem yeah bunch of places can't get to here why is that that's pretty weird if I go all the way to the end is that still true that was where I was testing originally yeah it's even worse so why do these ones not have be able to find a way up all right so now which direction is that axis so that's the negative y all right so if I just start a search from a negative y offset the same x negative 8 on the y and then the range of these same x negative 8 on y okay we subtracted 32 so negative 8 would be you just want I to be 32 and then search the full range of case all right so that should be one that fails so first of all let's check one that succeeds and make sure it's about where we wanted yep okay we're gonna try to pass from there to here we get up on here and sure enough it doesn't work okay so now we can go into the path find right here and press oh all right so we got to here it's gonna fail okay so it's gonna get to here so it's gonna run a bunch can we check how many nodes got allocated so it opened 189 nodes what was searching okay so why don't we get to see these we're gonna hit this code why do they not render debug nodes debug node Alec oh because we don't store the offset that it needs to use which what's the offset it needs to use to render these last pause all right so we need to set last pause we need to do that only only if it was able to fit what's the public can stand there's a public version of that where's that can fit can stand AI can stand so we want to say I can stand except we don't have an AI well I'm not sure we ever use that you might not use it yeah I can stand I set behavior from oh doesn't actually use so okay so we can use it I can stand back to UI and then also last time this one it does not actually show us the notes because it failed or something there we go that one that's the place that it searched from those of the notes okay so now we get up here search it searched around here it wasn't willing to go search over here for some reason it stopped why did it stop why didn't it expand into this node just needed to expand to here and it would have found that it's like it's stopping it goes too far but there's nothing in the code to do that hmm I know why that would happen I mean we've successfully searched really long paths but I can't search them out because I it's only searching from a little ways away now why did it try to search from there that should never have worked that shouldn't be a valid path why did it that's weird this where I was I don't know it's not it's got a dot here so I can't point tell to that let's just do it from 75 only 75 but there's two blue dots why are there two blue dots because it never overwrites the old one yeah yeah all right so if we do it from here it gets up to us if we do it from here there it doesn't it starts going up and then it just bales so why is it bailing it's that implies some of these nodes okay so let's color the notes for whether they got expanded or not or what are the statuses they open and a closed okay all right so if the closed we'll keep the current color actually if they're open we'll keep that color closed well we use that color for closed we'll make them red if they're open so the border the frontier should be now it shouldn't be able to if it doesn't find a path it shouldn't quit and leave any red notes if there are red nodes left it means it was supposed to expand them okay so somehow the open list is returning null but they're still red notes but the open list okay so let's switch to the old implementation of the open list I think that's all pat lined yeah I don't know if it still actually works but I guess I have a bug in my new open list code yep it found it to me that makes perfect sense all right so there's some kind of bug in the new open list code that's causing it to fail to expand to fail it's causing it to lose track of some nodes and they don't get served so so we have the numSecondary numPrimaryCounts so we can check those so if it runs out right here assert and see our numPrimary equal zero and see if that's true because they're those should only be zero if there's nothing left in the list and so we'll see whether that's incorrect or something else is incorrect okay that's incorrect so it's returning that it can't find anything even though there are still things in the list so get smallest open has some kind of bug all right if there are any in the primary then we go through and find it else we get to here that should never be hit because there should have been one in the primary so one path possible path is somehow we go in here we miss them all and there's there's one in here but somehow we don't catch it and then we just discard them at this point that would be a possible way to fail let's check that so this is a pretty common pattern for debugging you have a bad case you figure out how to make it reproducible you narrow down the things yep okay so sure enough you narrow down the the things that could lead to that bug in various ways test various hypotheses for what could be going on so now how could you ever get in here and then still miss one even though there was one in here well the only way I see is that we have this first empty optimization first non-empty so we can do a quick assert here and assert that they are actually empty and I'm sure that that's what's breaking here so somebody is not setting PC first non-empty correctly we set to zero in this loop and you Nick can never add something earlier than where the last one was so when we return one we update first empty to that list because that was the first one we found it could now be empty but we don't check that but we won't ever add anything except after that so I don't see that one going wrong and then when we update to the new list I don't see that going wrong I mean initialize it correctly there's their special case for initializing list where's I had to open list I had to open list what happened to the special case oh we moved it out we hosted it out to the beginning first not empty is zero we always initialize it how does that go wrong zero here it seems like it's got to be this case but I don't see how you could break this case you certainly check when we add to the primary list we're adding to this list list so we can assert list greater than equal to PC first non-empty that's not true you have a bug not sure which one we hit no we didn't hit that and we didn't hit this so it's not the case that this is broken okay I just it's that all that's in head yeah okay so the first half really is empty the second half is not empty okay it is legit to do this because none primary isn't counting for the difference between the first list in the second so that's not a bug all right ah this is incorrect okay because that primary accounts for the other thing so then what we do is we take all these take a first and we update them etc but we do need an empty case so what is the empty case if updating to the primary like this and the primary is still empty and the I guess it's just here all right there we go I think that'll fix it there we go it made it all all right great I fixed it need to remove some debugging let's get rid of this assert loop so we don't pay that cost in debug let's turn this back to the old test just in case we need it again let's test it I'm all come to me all right it's working oh there's one that's stuck oh you can say we get to me now but we'll allow for that well one of them can get stuck once in a while and be able to fill the path fine that doesn't seem the end of the world not necessarily bug you might have been in a bad place here in my spot I have to decide what to do next hmm I don't know what to do what to do what to do what to do what to do networking well I stopped networking because there was really no gameplay to network so maybe doing gameplay that can be network would make sense player hit points so you can be killed I think I would go the other way first give them hit points and let you kill them just so I don't have to deal with player death could render them better you can at least render them with facets instead of just solid color for the whole thing we could do we could do this thing we could do this I think this is the right one yeah okay so this is a player object being represented as a sphere and you just you know the control system looking at from third person control system lets you move and jump around when you jump it squashes and then pops up and then he evolves this system into a better-looking system that still has the exact same underlying control system and still moves that sphere exactly the way the sphere has been moving will be moving throughout the demo it just keeps adding layers of graphics onto it and it's going to a good destination as you'll see the nice thing about this is I understand how to do this how to do this bit basically from this video I learned how you could how you could do this basic idea and make it work reasonably well so right it's not the greatest animation in the world but it's entirely procedural and it gives you the exact same controls that you had in that opening sphere thing like the animation just runs layered on top of the existing movement and you say your movement doesn't have to take into account the animation in any way which is nice for game design because you just tune the game movement exactly how you want and then the procedural animation figures out how to make that motion make sense and I did this before I actually have this in my old ZMC demo that's the thing that preceded SP Boxle render and I showed it I think in one of the streams I showed it a little bit but we didn't look at the anime characters a long way to end this game yes it's going to be a very long time before this is what to refine it and make it look gorgeous takes ages yes but this is a block game so we can stop with blocky and graphics it's just having the animation for the motion looking better than nothing I don't know what Minecraft does I haven't paid a lot of attention to it I guess it's just doing that with the legs or something I don't think it has joint joints in the legs also reacts to walls etc yeah the version I did was not very refined I didn't even tilt the player and there's a lot of subtle stuff like that but he says it's really important because there's a separate talk on doing this but he doesn't talk he doesn't show how to implement just a more sophisticated it actually creates keyframes and animates between the keyframes in various ways rather than defining the keyframes purely procedurally which is what we'll do so I believe I have a third-person view but I don't know that it's hooked up currently because I had that for networking or something I think so third-person okay so there's a bully in third-person the renderer will allow you to render it if it's in third-person mode and then do we ever set third-person so let's just set it to true and see what happens okay so here I am in third-person I can't actually turn the player anymore because the camera don't know maybe it is turning the player while I turn the camera it's also turning the camera yeah that's probably true because we can't tell because it doesn't rotate the box is that true do we not know we do rotate the box if the player turns so I think in this mode it is not turning the player so we need to tweak that no we don't intercept the mouse here don't we rotate no we just draw the boxes without rotating them it's right here okay I didn't realize we didn't rotate the boxes so translate that is that right or do I need to go negative I think that's right yeah seems right it's in the same place and then you need to rotate after or before and XYZ so it's object I dot hang Z except that's probably in the wrong units no it's in the right units because now now we have a locked view okay so right now the camera is going to be locked behind the player facing I can't decouple it so we can't see the player from the side so I need to add that so where do we position the camera third person Camang where does Camang gets out so right here let's do this and then Camang2 plus equals third person angle and then how do we rotate that how do we deal with the process mouse a date view and what we want to do is excuse me I think we want to just test like if shift is held but I don't know that we have any way to do that we don't keep track of that currently do we get that as part of an event and then we don't have that event anymore process mouse yeah we this has that information I'm pretty sure we don't get on a complete on this what am I looking for I actually want the structure associated with this okay that's probably this it does not as deal does not include that oh it does it has this Sdl button state no that's the mouse state it's not the keyboard state is only the mouse mission event valid when you get to this you have to catch it yourself I think you do that's lame it's just really common when you get mouse input to want to know the state of the shift keys and the space bar and so having that just automatically passed into you by your framework is really convenient instead of you having to track it yourself and it's really easy to write that in the framework because you can always just pull it explicitly you don't have to add extra tracking you can pull it from the underlying system so I always do that in my frameworks and so it's sucky when Sdl doesn't yeah I don't think yeah it's a union so I don't think there it is possible so I have to test that so I have to catch that you get a key down event on the shift keys whoops I want to go up where's the set need to get multiplied by nothing okay that rotation is being applied at the wrong point and it's too fast although of course it's probably resolution and sensitivity dependent this is a conscious decision to use OpenGL fixed pipeline in 2016 I'm not always using the OpenGL fixed pipeline I'm not sure this has been discussed many times in the thing but it's probably not in the fact I use the immediate mode stuff for UI and debugging and I use the vertex buffers and stuff for main rendering as you can see there are in fact shaders and as I was discussing a few times previously I have a new OpenGL framework I won't switch to this too but and it just re-implements the immediate mode stuff from scratch so that you can just use core GL 3 or 4 and it layers it emulates the old stuff on top so you don't actually need to get the old stuff if you're on a Mac or something that doesn't have it okay so then where I'm applying that rotation was main rendering in main somewhere Camang right so then we apply the camera rotations and we move the camera to there but we want to orbit the player so how is this orbiting the player already I believe because it's relying on how to space the world space negative 5 right here so we actually need to offset that look at it from a different angle all right so so what do we do let's be more specific well camera all right so now what we need to render it as a bunch of pieces and let's not worry about doing that through a shader let's go ahead and just render them as pieces that's in main still somewhere in here we were rendering them render objects right here okay so player although actually this is when it's opponents it's going to be this type all right well let's make it work for the player first and then we'll put it onto NPCs render player orientation is currently this three vector thing I think that's okay back to computation I think for even for the non immediate mode stuff I still use the matrix stack built into GL for the you know I I'm still using the old compatibility GL underscore model view matrix kind of stuff in the shaders and that's one of the things I want to enable support for because it doesn't make any sense to abandon that stuff because you still need matrix matrices and matrix stacks and pushing that out to a third-party library that's different in every project isn't actually productive so I think it's better to actually leave in the compatibility matrix stuff if a player or butterman walks onto a conveyor belt can they ride around on it not right now because these guys live in a different simulation domain than the logistic sim so we have to explicitly generate forces from the logistic sim when they're standing on conveyor belt which we can do and we will do eventually but I haven't done it now right so much of video games are illusions like that where everything behaves consistently but it's only because you went and explicitly added code to force the consistency so we need to draw a box but a better box than we're currently drawing because it wants to be faceted with normals so let's go find the draw box code oh look it has normals all right we just don't have lighting on so I guess we'll use GL lighting which we have to do outside so GL how do you do this stuff and I never do this this is not this is going to be doing it in this year you know need to be smooth and that could all just leave in the end anyway okay it's invisible or it's this little box now wait what the pass in the wrong RGB that's not what that's not the RGB thing that's something else drawing or something I still pop matrix oh I didn't push me okay so either is drawing behind me or something or it's not drawing there it is if I enable lighting goes invisible you know disable okay I was turning on lighting make an object disappear does that make sense to anyone all right so so the existing lighting on everything is total hack it's just I picked some numbers for each direction so you can't exactly get them by turning on the feast lighting you won't get an exact match but we can get a little bit closer how do you do the GL ambient is that just attached to each light I think it is so I think it's just a deal ambient just assume that don't you have to set the light brightness yeah diffuse so let's move the light above a little bit more it's an ambient still a little dark do I need a matte ambient as well yep the default is point two point two point two one oh all right so we just actually need to crank up the ambient light all right good enough it doesn't really fit the world but it's good enough and let's push the camera out just a little bit more where was it that we did that where are we pushing the camera out there was a thing where we were calling oh it's not where we draw it it's where we read the camera right okay it's not sticking up out of the ground properly so why is that that won't have anything to do with the camera that will have to do with how we're rendering it smooth Z for rendering bump of it bump bump plus the average of the camera bounce because then we draw that so we actually want this to be the bottom not the average I was thinking I was trying it from the center but I'm not trying it from the center or no oh this does drop from the center I bet we'll have to look at it SPGL yes it draws from the center so this is trying to find the center of the object you take the bounds one and bounds zero and you average them so this is negative two and this is zero you get negative one the size is too seems reasonable to me seems like that'll work but it's clear not it's clear off by one somehow one two minus zero two and two plus zero two over two seems right to me why would that be wrong make sure we're on the ground boom break here I was done Z okay we're apparently four point five units tall and what to zero that doesn't seem right where is that five it's in the world I do the wrong order zero to okay this claims that we are supposed to be two point five units high not four point five inside so where did the four point five come from camera bounds okay where's camera bounce defined we just manually set it in fact I don't know why it's using this at all anymore why camera bounds even exists let's get rid of it so being you somewhere else yes and have a better way of doing this some time your size for tight everywhere all right so now maybe that will look a little more seen you can see it interpenetrates while it moves up because that's a hacky animation move up the object teleports up and then we smooth the Z position so it moves up gradually alright so we got those rendering now we need to add legs and arms maybe I should add jumping maybe I should add tilting what is it that you do when you tilt you need to tilt into the curve and I'm using or their angles that are oriented relative to that so sideways tilting can be done by banking up and down tilting so yeah I can probably just do that directly so so if you're traveling we need to know which way you're facing okay so back face equals let's where's the render player oh it's right here so this is in degrees that's alright so that's the direction you're facing and then the direction you're traveling we want lean in that direction so zero and the normalized vector for that we can dot them so what the magnitude of your velocity and then so then if you're forward so then we find out how much of your movement it's forward is face and then the amount of it that's forward we want to turn into tilt XYZ facing along why if I remember correctly so it's X so then if it's forward be told by a large amount so that we can debug it alright and then I don't actually apply that here so what order do you do these in or maybe maybe but not you can't see him anymore he disappears when he stopped but that is blowing up to zero well why is angle blowing up to zero oh it's this mag is blowing up mag now that should be zero norm move is blowing up because the length is zero oh but I am still tilting it by tilting the camera okay let's take out tilting it from tilting the camera no ink dot zing dot X so now if we move forward nothing happens backwards nothing happens alright so it didn't really work it is doing something I just I know what the magnitudes of these velocities should be so I don't really know how much to tilt it so there we go once we get a lot of speed it's tilting really far unrealistically and it's breaking when we stop it's breaking and it's not really right I think it's pointing in the wrong direction actually well it was partly because the physics is really weird and doesn't redirect your movement forward fast enough so maybe I need to fix that before it's gonna make sense but it's still also disperking never mind them that the amount of tilt is too much but as possible this is backwards I don't think so just move in a fixed direction it's only happening if I totally turn the camera away so I think it's this thought isn't correct is that rotated from the actual direction that doesn't seem why is it discreet too as I normalize but I have mag from before I normalized oh but I don't use Mac yeah so I don't want to normalize I just want to do that sorry I haven't actually even gotten close to doing the thing I said I was gonna do just trying to get why is it rolling because the speed is still constantly increasing doesn't make any sense I guess it is alright so the magnitude was is just way wrong alright there you go he's leaning into the run leaning way too much but and then this is all just bogus but that's fine because I need to fix the physics it's back so lean a little bit less backwards very suddenly alright there we go now we've got the guy leaning into the into that stuff he needs to lean into turns as well but this is we got a fixed turning to actually behave better first it's the physics for that it's just busted that's just not how you run when you turn like that you to already be running that direction all right so let's check that in running there's this face behind my ambient tickling my OCD yeah that's actually intentional because I was gonna do that and then I never did there you go okay so now we need to fix that physics so that's in the world because I need to move it into physics and player physics so the thing is basically that this physics was what made sense for flying and it doesn't make sense for ground movement just kill this I don't even know what a store move them along its velocity when you thrust me redirect its velocity so yeah this is all sort of like a aerial thing so flying and we'll do it the old way obviously that doesn't apply here okay so why do you do physics when you're on the ground turning in 3D do you just let you instantly turn you let you instantly apply all your velocity or do you just rapidly decelerate the velocity in the wrong direction I don't know I don't know what the right way to do this I'm not sure I've ever done this yes I did in CMC could check what I did there you said you desired forward and sideways speed because you can set step and then you accelerate between them and you give some max acceleration so it can smoothly adjust I guess that makes sense so do I even have sideways oh yeah that's this it's created as effective Excel which is not really correct so what we want to do let's do it first to as we want something like this and we say this is sidestep speed this is speeds we need to rotate them into world space all right so now that's how fast we want moving the world and just slam the velocity to that to test it no we need a run speed I have no idea what they need to apparently those numbers are way too low wait sidestep is fine well not fine by sidestep it's faster than forward backward how is sidestep faster than forward backward that doesn't make any sense I have another bug with the directionality here somehow we'll see how it's just overwriting it x y z how is that doesn't make any sense yep this is still really slow oh okay I just have these backwards this one I'm writing along right that's right because I always use the y-axis not the x-axis so that was too fast that's actually a reasonable walk speed maybe and run speed should be faster then if I do that you can see tips a little bit but it's not really done very fast so side view should you be able to run faster than this is this a reasonable speed I think this reasonable speed so I should take off third person per second to check well you go just a little bit faster just for help so then it's not that it's good if mag is greater than run speed so if your combined motion is faster than the max speed you should be able to move then we need to account for that and we say equals times equals limit your speed to run the speed to prevent running diagonally from being faster and then now we need to do that acceleration stuff that I was talking about in the other thing so so now we need the vector difference you could do this directionally and that would make for better turning curves but we'll just do it slowly to start with if mag is greater than max so so the player goes from 0 to 12 how long should that take maybe half a second so that and so greater than that then see how that goes need to get a vector mathlib in here to replace this all this manual vector stuff and I totally screwed something up and it allowed it to go way too high x times change not x let's change that one change that y that's too big and we shrink it I'm sure how that would allow it to go too big but okay that's the backwards it seems to be allowing it to increase without bound which is not what it should be able to do and it shouldn't be backwards so what's going there this is a desired velocity I'm pretty sure that's all okay this is how much we need it to change by per second so much we need to change by total max is the max change per second so we clamp it it's bigger than the max change per second so this needs to be a change per second but it's just a change so do I need to multiply it by dt no because that's not seconds that's arbitrary units I'm gonna do that over here the actual forward vector right we rotate it you'd acceleration impulse and we limit the impulse do the same adjust let me add it come wait where does the dt get entered in oh this uses a fixed dt that's why this is changes in units of velocity why don't I work at a big game studio because I don't like working on large teams I'm less efficient and so my morale suffers and I did 20 years ago work at a famous studio what am I missing how is it that you do this you've got change that you want to do and if that change were done over a second you would compare it to that and so if the change is more than that then you reduce it and at that point you have the change per second that you want and then you multiply by dt that seems right all right what happens if we just do this because it seems to be blowing up in a weird way which I don't understand it's it's negative like first of all why is that negative okay the old thing to do was to go oh velocity dot x equals 0 let's don't check that but that's still correct yep okay that's working so we're trying to approximate the effect of this gradually so we check the difference between what it currently is and what that is and then we'll add it so if we did this shouldn't that be the exact same thing no because I'm subtracting in the wrong direction okay yep yep yep yep yep okay although this is why it was negative so now we're still just turning on the dime because our max excel is pretty fast I think it wants to be pretty fast and we just can't do that here but let's say we make it take 2.5 seconds to reach max speed and see if we can actually see that be gradual no not really I'm not sure that's right like it does the full tilt instantly no it's not taking that long term sorry so I'm still not doing something right here oh I took out a times dt now it'll be way too slow yeah and it needs to be a different thing for slowing down than speeding up it's going to very gradually tilt we ran into I think our speed okay it does not seem to be tilting as much as it used to not sure why that is let's put this back to 0.5 I guess I put the tilt back to being pretty subtle intentionally because it shouldn't be that strong it won't put back up do I plan to integrate Louis scripting probably not but it's possible because you will be able to just modify the source so people can do mods that way but for mods that you want to like distribute from a server to players maybe you need something like that and I could write my own scripting language and nobody would be happy with that so maybe I have to do Lou in the end I don't know not super fan of Lua I mean that's okay why is it tilt more that just cuz I'm the angle I'm not it seems to tilt more backwards and forwards it is tilting more backwards and forwards maybe I've measured those directions backwards oh yeah because I have to reverse the sine and cosine so it's actually measuring these backwards it's just that no now it's worse wait but I just negated it so it should oh by all indicated one but now it's tilted backwards okay I don't want to put it back the way it was so now it's too far that way and we should just limit the backwards speed probably rather than limit the backwards tilt but oh it's kind of nice for gameplay reasons to let your face backwards and run at full speed so maybe I shouldn't do that noise let it be user-defined alright so there's some basic movement it's still you still get a long way when you turn so maybe I wanted I do want to adjust that how do you adjust that you don't want to skid that far so this is the problem that I'm using the same acceleration for changing your speed and for redirecting your speed so what I want to do is make those use different exhalations so turn itself should only take half a second to change I guess that's just way too much try that I guess okay so then how can I distinguish these cases so we want to break this into two steps so in the first one so the first one we redirect your existing speed so so we get the magnitude of your existing speed desired speed now we could actually do this based on your facing direction and try to only translate your forward speed but like if you're running sideways your side stepping and you turn into that and run forwards we want to keep that speed as well so it's easy it's just to look at the magnitude and not worry about that so so if it's a magnitude preserving so what we do is magnitude two and we want you to slow down quickly so we'll actually put that the slow down case into this case as well so if mag two is greater than mag that we clamp mag to the mag so that's the amount of speed that we're going to allow you to change so then we do the same change thing but now we re-normalize so that's time this best change mag over mag two now is that vector to property it's maybe not maybe it is okay so then we allow that to do max player turn excel then what's left after that we accelerate with the regular stuff and that'll actually because of this dt change it'll actually double apply this but that's okay one of them is huge this one is huge and this one is small so the leftovers in that that could still go through this path but that's okay and I blew up yep blew up what did I do run speed over 0.1 f mag 2 could be 0 right so now if I turn it still skids a bit which does mean you have a turning radius that's kind of realistic but still seems slow I told it to do it in 0.1 seconds it does not seem to be doing it in 0.1 seconds so I wonder if the logic is wrong it does not seem to have anything to do with what I just said seems to just still be doing it I think it's doing it exactly the same as it always was as if this code is not doing anything but I do have it if one or inside speed I mixed up in line 170 well this is backwards but I think I compensated for that by now right yeah exactly these are just named backwards at this point so why would this not have any effect player turn itself is much bigger so because this change this because I can only do DT of the change and I'm not clamping it's not allowed to get bigger right the change right if I want it to happen in 0.01 seconds it's gone multiple change by 0.01 here then change needs to already be scaled up by 100 of the actual required change but I never do that I don't scale up change so what I want to do is renormalize mag so it's actually at max by your turn Excel and then if it's too much change back it back down if I'm thinking this third correctly crank it up multiple by DT and then if that's more than is required to do this so it actually is is if change that X times DT max clear turn Excel well that's that's not really gonna change anything doing that don't change anything yeah so maybe it is whatever saying do this greater than you have a sign problem with checking greater than here super annoying you know what this one is I'm calling it scaled change if that's greater than the actual change less than equal then we clamp change well this has to do nothing because language it was zero so just change something like that maybe I don't like how these axes are independent here it doesn't feel right but okay well it's still the spazzing the velocity but it does change on the dime and it's doing some kind of axis fuck up here so it's totally broken and we'll have to redo the same rewrite down here but I just want to get it right first okay so we take the fraction of it well sir let's just force this to do the full thing let's have this branch handle all of it watch its spaz on its own okay and it's like never it's getting stuck in midair and not doing anything or something it only changes when we bump into things why is that going sideways there why is it not going the direction I'm pointing and there it probably is this is something really weird happening and of course it mag 2 is zero this will never slow down currently because of this but that's not the case that we're dealing with mag is always mag is not zero once we're moving oh this mag is just the ratio between how fast we're going that we changed by fests changed to mag 2 so this is just this is just a change that's just a change and we have this weird stuff magnitude of the change try to sell us huge now this we've allowed this to be huge but then we multiply by dt if it's smaller than the desired change we bump it up to the desired change but the larger we keep it isn't that backwards although I don't know this is all kind of fluged okay there we go okay now we can turn on a dime so now if we bring this back down we make it a little bit less turning on a dime but relatively dimey yeah so now if you whip turn it takes a little bit before it catches up okay so then if we only apply that to this part and like I said I probably need to copy that code down to here but let's just do it one step at a time alright so we gradually kill up to speed but we very quickly change our direction and we very quickly stop because the stopping code is currently part of the I think that's reasonable need to lean into turns still but whatever they decide steps I guess should I now just leave this but this one instead of switching it over to the other thing yes but I don't care about that so okay so I think we can start doing the adding those arms and likes all right so it's in main render the player okay so now what we're gonna want to do is have limbs that have orientations that are going to be matrices and stuff so I think we want to go ahead and grab a vector library where have I seen it hello fire engines this is a good one or not we're turning in yep okay got a bunch of stuff so we'll try this one and then what what do I need to do I need to start using that so data that's how that one actually works we'll have to check in a second not included that redefinition yep that's correct we want to get this out of that library now but it has a different it has different definitions I'll have to rewrite all the colors these all it's all like this of course if they start with the same one you can use sub and scale and scale equal but that's the only one that does so we want a mother I don't know if it has some scale though actually yeah it doesn't back it lives so big and scale edit scale okay time sort of formal parameter three back and scale back back back foot oh that's just yeah I have to move these guys so we didn't miss any warnings here so switched over the vector library see if it's all still working break anything check our rendering of these things okay so shadow on the thing okay it's all seems reasonable alright so now we got a vector library how long is it taking to get to this stage in the game well there's a huge YouTube playlist so how long is that YouTube playlist because I've done all of the programming on stream so I'm and since the playlist is a mix of two hour up to eight hour videos it's hard to say right we're on 48 but I don't even know so it's you know I don't know somewhere between a hundred and four hundred hours probably second how did you learn C++ well this is actually C not C++ but I learned C and C I probably just see in college and then used it on my own independently at the same time that I learned it and after having learned Pascal first and then I picked up C++ probably outside of school because it was needed for the industry and picked it up on the job basically I guess probably my first job not positive finally is Java good I have no opinion on Java I have an opinion about object-oriented programming and Java pushes you down that path of course but alright so now we can have the matrix these and vectors so here's a question should I do this from scratch or should I look at the ZMC code and use that to guide my implementation of it if I do it through the ZMC I can probably go faster and still explain everything if I do it from scratch I'll have to figure out how to do this all from scratch and maybe that's more interesting to see how hard it is to do it from scratch for a knowledgeable programmer so we want the player rendering player rendering player rendering oh it's not world it's main making that mistake okay here's player rendering so the player is going to have to have some limbs but what we'll do to start with is instead of having to be stateful we'll just solve for their limbs from scratch every frame that way we don't have to store any extra data also I kind of need to I just had breakfast well it's three hours ago maybe I'll just make a little sandwich it's 1 p.m. so hang on let me just get some I've gotten a knife I used to me because it's the language I'm the most productive in I didn't find the stuff the extra stuff available in C++ was actually evapnous compared to C so what do we want to do we need matrix representing the transformation for each limb and we have to solve for that I mean I guess I could do it though actually tough I could match the video a little more so I don't actually need those yet I just have to draw some feet without worrying about the connection between the feet and the body so I do that first and then I start drawing the connection multiplication is significantly faster than division on almost every platform specifically to precise division it it's either integer or if it's required to obey I triple EU rounding so on GPUs it can be a little more flexible but on CPUs it's pretty universal all right so what I do is draw the upper body I don't know what's gonna actually make sense here may have to rejigger the proportions so I find where the bottom of the feet are let's draw the feet well let's draw the feet in the same spot and how big should the feet be and I'm drawing from longer in the y-direction we could draw them inside the transformation and then they'll pick up the tilt and I don't want them to pick up the tilt but I do want them to pick up the rotation so I just need to compute it independently which means I don't need that although I actually would like the feet in world space now they're invisible because they're inside the box probably because this was before that got computed yes I still want this before it is it tilting or is that just the camera tilting yeah okay all right now they're not on the ground why they're not on the ground now that should be the ground oh because we're now that should be where the ground is relative to this oh no it's not oh yeah it is over to what if we don't do that it is on the ground and it just looks like it's not on the ground to me so it's no shadow no it's definitely not on the ground why is that not quite on the ground close but not quite how much is them up some centered size past in the real one and check that that sure seems like the top not bottom it is floating in midair well I do have a fudge where I keep the players position slightly above the ground but I didn't think it was that big is that physics where is it that we do that walkable Z epsilon how big is the epsilon now Z epsilon is tiny I'm seeing a pretty huge no that is not Z epsilon all right let me break in there and see what the numbers are obviously 72.0 oh I offset the wrong one here the wrong amount I mean there we go so there there's a foot on the ground we need to split to two feet which means we need the direction which is n.z which means in this coordinate space we can actually just push them sideways I think x is forward so this will be negative 3.2 maybe you know push them in the same direction but we were looking over it we look a long line right okay there you go there's a pair of feet that stay under the player they pop up because of the way we do the step-up cheat because they're not allowed to inner penetrate the ground basically so they pop up all right so now let's have them animate or there's a DT DT so we have a global timer let's have a current DT DT state all right and so then what we do we compute the state animation DT times plus equals animation DT times how fast do we want this to move one thousand one one thousand two one thousand three so I think that's about three per second so three times per second means we want to go through six point two three times per second so about 18 state and then so why we'll move with C and it'll move by distance of three two opposite signs there's a running thing it's running backwards all right let's fix that so we need to get one of these to fix that so here's some running feet let's spread them out a little bit more and move a little further all right now we want this the feet stepping to relate to the speed that you're going at there's some correct math for that and I'm not going to worry about the correct math that because because I'm not gonna stick with this system in the line okay so now it needs to be rescaled by some amount and I don't know how much that needs to be rescaled by this in parentheses before okay now it's running really slowly it seems like you have to put it back up to 20 oh I've left out mag I don't think that I don't think that's really matching I think that's sliding a lot but main issue is they're going under the ground and I can't get them to stop side by side here so I need to actually do something special for the side-by-side case but like I said what I actually want to do is start doing foot placements where they actually match the terrain so they don't enter penetrate the terrain at all so it actually has gone query for collisions find where it can put a foot and put the foot down there so how do I want to do that so what I want to do is have this bead of the motion still be controlled by this animation thing so I assume something like 1.5 is gonna be right but let's make it even faster just so I can see what it looks like okay one problem is it's using the falling speed to help compute how fast it needs to be running the feet yeah I think that's too fast so that needs to ignore so that move 0 so now we need to make skinnier or thinner vertically just because they're still going under the train I want to fix that because they move vertically by that much so we have to add that much to this but now when you stop they won't be on the ground that's okay we're not gonna actually use the this ellipse that was just a starting point I think they're still under the ground a little bit but whatever yep they are yeah I don't know why that is I'm not sure it's worth fixing oh because I increased the wrong thing all right so globals are the easiest way to solve lots of problems there but they are risky so you and we had a bug last week due to the globals so you know it's usually worth it if you know what you're doing all right so what did he do in his video after that stuff here he just had them on the ground facing the right way okay so he makes them when you're staying still makes them still get up and down it makes the distance velocity dependent okay that makes sense so why his times mag scaled by something I don't know what it needs to be scaled by and he didn't make the speed be yeah that's a little silly he didn't make the speed be speed dependent I don't think because in real thing you don't you have a couple of gates that control the speed but you don't do that we get rid of this something like this I don't actually have multiple speeds a moment I should have multiple speeds a moment so that I can test that I don't know why close it I need it again he has a jump thing that I don't have to jump you can see the lean you can see how he has his lean forward okay then he connects them with the joint and his feet though are solidly placed because he did the math to figure out how far the steps need to be to to match a given speed and I haven't done that math because I want to do the exact placement instead so the next step is exact placement okay so so that if almost never happens for any programs I see that's an if in what I'm saying about using globals but I've been using globals my whole life before I was like as good a programmer as I am now you just learn by doing so start using the globals and occasionally you'll screw some up because you have globals I mean the other thing is to never be scared to move things how to being global's the whole point of using the globals is when you know you only need one of things I'm not only going to need one of things I know I'm going to have to have this animation state be per player but it's easier to get it working without adding it to the player it's easier to just get it working once and then I know where all the globals are and I can isolate them and move them into the player have you always been able to maintain these long sessions of intense productivity yes I'm better at it I've mentioned this before I'm better at it on stream because I can't goof off but back in the days before the internet's when I was learning to program in my teens I definitely would just sit there for four hours and program program terribly but program all right so what we need to do how do you do this so currently there's this implicit state because we're just using this ellipse computed here where the foot switches from moving backwards to moving forwards the idea is that to for this animation to be correct the backwards movement needs to match the rate at which the ground underneath this moving backwards which I haven't bothered to do and what I want to switch to is a stateful thing where I don't need to keep state but I need to know which phase of the animation I'm in so if I'm in the moving backwards state it will be stable and pretty quick if I'm in the moving backwards state so this foot let's call this the left foot I don't know if that's how this thing works out I think it does the left foot so the left foot is moving backwards if C is less than oh right so here's an easy thing we can do that I forgot to do let's go ahead and say why left why right Z left the Z right so left why what's why left right is that and then we're currently just using the negatives for this so we can just do that and then cheat that to why left right now the smart thing that we can do is if Z left is less than zero so now instead of following an ellipse they'll follow half of an ellipse and then move flat and that means we don't need to add that that should help this motion a bit it's weird on the oh they're synchronized I forgot to negate them it's weird when it's in place they'll do this weird lift one foot at a time thing let's make it a little slower and make it higher now that it's not going under so you should make sort of a half moon shape where they where they yeah do that they followed an ellipse on the top and then they are flat on the way back and like I said the backwards speed doesn't match it's too slow I think I don't need to get right because I'm gonna switch like I said got switched to just explicitly computing a place for the foot still need to come up higher it's too spread there's spread way too far but I think that might be necessary to match the velocity yeah looks pretty close to a velocity match so we need to up the speed and reduce the magnitude proportionally that's incorrect when it's backwards it needs to reverse the animation directions that's fine all right so now right foot so left foot planted zero right so when C goes forward it's lifting the foot and then the foot lands at right when C starts going down from it hits its max at C equals one and then it starts going down so if C it's less than one and so we really want to know this state animation state equals so if that's the case we which what is the cycle where C C 0 to 1 and then it starts going down again so that's at 90 degrees so if C is greater than equal to 90 degrees is pi over 2 4 2 and left foot planted then we want to plant the left foot so how do we plant the left foot well we want to switch this now to world space which means this we can't have that translate which means we need to do the rotate separately and then that means we need to do the translate before the rotate right before after before that is at 0 0 0 which allows it to rotate around the center of the box which isn't really exactly what we want to rotate around but it'll do and then for this to work these need to have already been offset by plus a wine plus but these are in the rotated space wait right so we have to actually explicitly offset those these in the relative space we need to rotate them what's called ob space towards space all right so that takes F put right put us back where we were maybe maybe maybe not this takes some other parameter what does it take this is the angle offsets hack for the third person translate FV translate BFV what is the translate why is there no translate FV my oh there isn't one okay right great thank you symmetric there is autocomplete there is coloring that I turned off you can watch the video if you want to know why so hopefully I didn't screw that up and this is unchanged but in fact I screwed it up their feet I don't know where the feet are I can't see them anywhere but it could be rotating it with the player are they down at 0 0 I don't see them could be inside this object then the same ballpark no they're not they're nowhere near each other oh this is using pods wait right this needs to just be relative now doesn't want to incorporate there we go okay so it's back where it was good good good good looks exactly the same but now I'm computing these things in world space and what that means is I can keep them around which means I can do the following planted let's just compute this every time feet dot z we need to keep around that state where we're computing it every time currently right here so this is dead yeah all right we were passing that into test to make sure there wasn't something going wrong there well we can you can actually so wait we still we're still inside this jail translate I thought we got rid of that thought that was the whole point was we got rid of that and we pushed it inside here but it was still working I meant to do there actually make that work yet so wait it was working but I hadn't done that thing so it should have been broken now one of the one foot works open it gets stuck that's great so it is still working no okay they get stuck back at where they were they're moving counter to it very weird do not understand what it's doing okay we've popped the matrix so the pause is not in there at all the pause is just the player I'm hacking that in here so we need to actually pass this in called object ID or OID so how is this position the ops face to world space is supposed to be doing that supposed to account for the player's position and push that into this so why is that not actually happening this is supposed to be a relative coordinates in the object space of the player and the output is supposed to be world space coordinates no it's just leaving the feet behind they're moving sort of counter just doesn't make any sense they're impervious to rotation that looks like yeah they're unaffected by the rotation which they also shouldn't be oh right I just counted out the rotation how are those not the right coordinates of space to world space is obviously the world space not doing what I think it's doing did I leave something else on the matrix here matrix mode push matrix pop matrix and do I do anything else I do any other jail translates no only these inside here are these coordinates not correct they're just a little displaced I don't see how those can be wrong how is that not the right thing how is this implemented just by doing it by hand why would this not be right why are these coordinates really wrong is this whole thing wrapped inside a thing no nope we set model view yep we set model view push matrix pop matrix push matrix pop matrix we translate forward not negative do we need to be translating negative we don't translate negative here nope nope it's just how it's position offset I don't get it why it's just broken what what am I missing looking to debugger but it's just wrong numbers and I don't know why is it correct at the starting position am I at zero I am at zero okay so it's gets incorrect as you move away from zero implying that there's just a sign error well except it doesn't it just doesn't move that way it's not I was saying it was countermoving but it doesn't look like it's countermoving that way it's countermoving this way or is it oh no it's just moving up and down because I'm moving up and down it's not actually getting no it's just moving up and down okay it's just not getting offset even though that's what obviously it's the world space is supposed to do I'm going to see why that's not happening here maybe it's not maybe I'm space-to-world space is just for a relative vector I didn't think it was though let's look at the function again oh it is it only looks at the angles okay well there you go it's not the function I thought it was alright okay so now it moves with me great now now that we got all that set up we can now cash it if C is greater than equal to m pi over 2 and left foot is not planted then compute that instead planted to true if C greater than equal m pi over 2 and C so just half of the arc 3 m pi over 2 so during this arc we plant the foot and outside that arc we animate the foot and the left foot is gone help we forgot to do it on the side okay now it doesn't look particularly planted so I'm either have a bug or it's planted and you just can't really tell so I need a slow motion do I already have a slow motion I don't think I have a slow motion main dt t times equals slow motion 0 ui and then if you press B so one thing you can see here is that the simulation has these dt steps that it won't advance by more finely then so you can see that happening here so then does it look like that planted foot is immobile it's hard to say because of that the dt animation so let's change that to create okay let's make our max to create be 180 the thing is it's always going to take it that slow at that speed so it slows down our physics all the time and toggle it that seemed to have gotten worse it seems very slidey to me but maybe it's not hard to say yeah wait why did that tick mode thing not work to create oh because we don't this loop isn't actually doing that anymore where is that happening then update input thing doesn't happen here who is doing that process to which has its own great okay I don't think it's used for anything anymore alright so now rotate slow mo so the right foot I expect a slide wait this is still standard need to put that in a constant alright here we go it's gonna work this time well we expect to have happen it's a left foot lands and it's just rock solid on the ground for a little bit it seems to slide I'm not sure yeah it seems to be sliding alright let's change the speed of it because I was I tried to tune it so it vaguely looked right so let's get rid of that let's make sure the built-in animation is wrong here it is right so that's this computation so let's make it step really huge and that will still run when it brings the foot back but then the so the foot should handle way far forward but ideally will be stable once it ends up really far forward okay why is the right foot not am I looking at the wrong foot I might be looking at the wrong foot why is the other foot not focused I only did for my left not my right okay so that is the right one so it should jump really far forward but then it should lock and it's clearly not it's supposed to go that far forward and then lock and it's not looking alright so left foot planet is true at once you hit this it doesn't recompute left foot at all during this cycle okay so let's while it's planted change its color see what happens okay it's never firing it's never changing to red to make sure that code is correct oh I see why because we're testing C we're not testing animation state so I supposed to be testing okay there we go so now not sure why it disappears okay so I got the phase wrong the phase where it's alright because it's at zero that it does that so gradient equals zero less than still should disappear oops all right so it's going underneath or something that's mom Z plus point five position no longer gets updated but we're using world space position so that should be fine push it up by one because I don't know where it's disappearing to so it's just draw it up higher a block higher and see you know it draws from moment and then disappears draws from over in the right place and then disappears supposed to be that why does it disappear are we relying somewhere in here on a variable that's not getting set left foot is global right left foot is global no left foot pause is global now it's stuck up a foot because I put that hack in all right so now I think this will work it's not do that yet okay now let's do it okay so it plants it I set the the distance thing totally wrong so the plant location is terrible but it's definitely stays planted once it's planted it's in midair though but oh that was because I was falling yeah okay it's not quite on the ground but it's pretty close okay so now if I put the distance back to a reasonable thing stop changing the color while it's planted do the same logic for the right foot opposite phase all right now we should have both feet planted and and of course when you go up and down it won't be correct but all right so there we go so then the next thing we can do is actually do things like where it tries to place the foot check if it's on the ground or not if it's not on the ground make the target be all the way on the ground or if it's up make it up so we can do that so let's check this in I guess it's we didn't even have feet before so that should have been in there as well did you try Vim and what did you think about it well I when I was on Unix I used VI all the time I used to him a little bit on a PC but not for long I decided to get used to using the IDE because I think I'm more productive in the IDE than using a separate editor so now we need a query for placing a foot and we have a can fit function the AI can stand so we want a variant on that external wall can place foot back location and we'll just approximate with the bounding box not the exact shape of the foot so float call them radiuses so that I know they're from the center out instead of sizes that are you have to divide by two so let's find AI can stand and we'll use that database rather than the physics database oh we don't need this up behavior we just need can stand actually I think oh we can stand takes the physics the path line database stuff that is overkill can stand raw is what I actually want to use can place foot so what we need to do is figure out all the squares it covers which is the standard and that still takes a path behavior so let's just let's just compute it directly instead of calling that so we just want to do this so we do j equals x0 j less than equal to 0 j less than equal to 1 x0 less than x1 get the chunk and then we just need to check one height we need the foot height to be open so if msc or pc.pathdata x.data of z if right for and then there's something in the way and we can't stand there then if one lower let's see ground we can do the same thing if the ground less than zero so same exact code we have below then we return any ground floor undefined all right right so the whole floor placement loop here thing is just the if you if you imagine the foot it's much more than a block you could just only test a single block can't it stand on the block that it's in and that's probably good enough but this allows you to place a foot extending across a block which may be or may not be worth doing wait this isn't right at all wait what was mesh chunk size don't we have to why are we doing mesh chunk size what is that modulo for because we're calling get physics chunk for a chord why do we have rx and ry over the path data right yes right mesh chunk size yes okay right I understand yep yep yep okay so this is just j okay can place foot so now we have a can place foot function and we can go in here and what we can do is whenever we replace the foot we can do this if can place foot location is left foot and the size is point three well how big do we draw it point two by point four so we'll make a point three by point three because it's not oriented the same so we just want approximate so we're doing it as if it's a little square left foot good let's just assign that left right foot good it's true here so now we'll try to test whether we're successfully detecting whether we're we can place the foot there so then we do jl material good that fuse off a bad mat red right so it'll turn red if the current code that thinks it's a bad foot placement but I don't know if the logic is correct different types take a non-addressed one yes it takes a non-addressed one all right so you saw what was in midair it was red all right let's go to slow-mo and notice it that it jumps when it comes off the ground and that's because it's stuck in an old position that has nothing to do with where it tries to do okay that one was wrong so what it's not accounting for is that the height is just totally not close to the it's rounding the height down it's not paying attention to the fact that the placement isn't even close to the ground so that we can do here that's this right so these are always zero so right here we can add the left plus equals bottom that's just the left right and I think the point of five is a fudge that we actually don't want anymore or was it to compensate for the thickness of the foot it might have been to compensate for the thickness of the foot I thought they were drawing a little off the bottom of the ground there so is he right is he right all right so now now these we can check if they're too high up so here when we go to plant this foot we want to do is we say if the left the difference between the left and absolute of the left not absolute sorry floor of the left so it's just frack but I don't think there's a frack function if that is too large then let's move it down but we're only doing this when we're planting it when it's in midair it's allowed to be up it's only when it plants well I'm not even coming close to getting to the point where I'd start drawing the legs in this is way more stuff than I remembered you had to do all right so well I guess cuz I did it in the other order the other time it so here's one of the things is like if we draw run along this right if we run along here it should just always be red right and you can imagine that to actually make this work if we actually want to run with locomotion here we've got to drop the right foot all the way down to the ground so that's the next step it should be now that now when we step off a ledge it should automatically dropping down after a certain distance but we have to actually be falling off so let's go to the side view and go to slow-mo and step off and see how that works the foot should teleport down once we drop a little bit boom yeah the foot teleported down to the ground all right check that in just in case what is this plant feet slightly you are aware of inverse coming back so that is correct that is how I'm going to draw the legs connecting the feet to the things the whole point of the inverse come acts as you need a location for the feet to do the IK to connect the feet to the body so I'm trying to get the location of the foot right before I do the IK and in the later videos in his some of its later stuff he like I mentioned this earlier is he uses some keyframes and animates between the keyframes and then he modifies the keyframes with the IK and this is just making the keyframes be in code basically and the animations they totally procedural but I'm pretty sure that's how he started in that other in that video I did show is started with just doing the the ellipses and stuff it looks like it all right so now the only problem with the feet planet is sometimes we get this case so now let's move this up to the beginning and now we can search for where to place the foot so we run that and if we can't do it we can say find foot placement left foot just do that and right foot and we want to constrain the movement of the foot so it doesn't move to the wrong side of the body you don't want the left foot ending up on the right side if that's the only place it can find a foot placement so we need some kind of bias to tell it that and so the left foot we actually need to object to world space to do it so up space to world space just need a temp so let's go 5 how do we want to do this we want to describe the area in which the foot can place as a polygon and then search within that polygon so we actually just don't want to go ahead and do this so how far to the side can your foot place if you need to stretch to make something weird sure like seven point seven it's pretty far maybe point five is the limit if you're all the way at one side of a voxel and can't place yeah it should probably be smaller you can definitely just fail to place some of the time because when you drop off a cliff you're not being able to place so that should happen some of the time so let's see made for and then forward how far forward can you place when you're running it depends how fast you're running you want to bias forward when you're running which is this mag that we have already except that's not directional so we want to actually bias it in the world space to pause x plus oh it's not gonna be called bias anyway more i equals 0 i less 5 oh poly so we will add the position to the point and we want to add a velocity some offset velocity oh it's move fell so some distance related to the move velocity which I don't know what the distance is so we'll just do something and then yeah we'll just add that to all so negative 4.0 and say you're forward place and backward place is also plus or minus 4 say this has what one extra parameter so let's make zero in the origin so this is a preferred placement this is where it wants to put the foot and then we'll give it some alternative place a range of areas that it can try to place the foot and sure negative negative positive positive negative positive positive then we can say fine foot placement of poly also a foot cannot be infinitely long and center of mass should stay the same yeah we totally cheat the center of mass you know your center of mass while you're running is out is not actually balanced like you only have one foot on the ground so you can't actually keep your mass over your thing but that's the whole strategy here is that we ignore physics for this we are just going to use IK and procedural animation logic and keyframing or whatever and there's no actual physics the physics just runs on the the sphere in the wolf in the overgrowth demo and the initial block that we had so this takes back poly so we start by saying can you just place your foot at point at the center point and if you can let's just return that great rock on if you can't then we're gonna search for other places that you can do it and we're gonna do that by this and we're gonna say float best dist and best s best T no watch just have best and the best dist is the distance from that again then we'll just loop s equal 0 s less than equal to 1 s will step by point to 5 place and this is going to be back I don't think we have a vex scale do we how we do so one we're doing a bi-lerp here I usually would do this by doing two intermediate loops do I have a vexlerp I do have a back but let's do it that way then place one place zero place one back to work that's the destination right this first it's zero two we're just brute-forcing we're searching a bunch of places we're on test each one and see how good it is very inefficient just want to get something that works so if so then we want to find the distance between the place and poly zero okay first we gotta check if we can stand there if can place foot at place and present on this one or does it not take one doesn't take one okay if we can place foot there then we check the dist if the dist less than best dist the best test has to be started at large that's less than best is the best place the best place maybe turn poly at zero scrolling back checking stuff yeah it's a $10 Dell keyboard it's just the the the microphone is the microphone is mounted to the desktop and so you get the vibration of the keyboard through to the microphone so it sounds different from how it sounds if it's in mid-air like here I'll hold it mid-air and type here's what it actually sounds like and here's what it sounds like if it's on the desk I can't hear so I don't know if that's actually different but I assume it is back at equal scale right that number to do tune 5.0 f that determines how far ahead it goes that's actually I can think about this how fast are you running it's running like three cycles per second or something so the movement dist is how far how much distance does it cover in that much time so it's like 3.3 f or something all right back at equal scale or types for formal move val it's a vector which one of these is wrong back back oh it's an at equal scale so we don't wait but we wanted to add the pause oh okay we can do that much more efficiently um I need to do the same kind of logic for that all right I didn't account for that uh right so negative four is the default foot placement 3.5 f so I wanted to go from 3.5 to wider than that so 6 to 0.1 say and then on this side it wants to be positive because it's on the other side and find foot placement right foot okay probably totally wrong but let's see what happens okay it's not turning red but it's also not placing it down at the right spot probably because I deleted the code that turned it red these are still adding these are still updating it yeah these are this is kind of in the wrong spot we do that computation then we did that then we did that right we kind of wanted to run all this after this I lost track of how I wanted to be doing this when I was doing it um we have to push that in as well what the z left then we find the foot placement and we can see it's true this is just to for this even if it's not planned we want to actually set that um that's to tell the state machine basically what's going on so does foot fit what is it called can place foot let's make sure we still get this state so this with that we find foot placement we know we're at these yep that's pretty busted they keep moving to the zero while they're on the ground even though they shouldn't oh that's because this is not in the right spot so it's it's trying to move the foot but it's moving it to a useless place oh I see what it's doing remember it's treating the foot as a circle or a bigger square so it realizes it can it sees it can fit if it moves it inward but it's not actually moving it inward enough to actually fit because uh because of that size thing so yeah let's make it skinnier because you don't want to land with just your toes on it anyway so we can in fact make it the small size where is that fine placement do that not sure why I did it once okay but so there you can see it's moving the foot to a place where it can just barely touch the ground but it's doing it in this weird discrete way and it's not showing invalid right now and it's not trying to reach down one so I need to allow it to reach down more which is not trying to do currently and up and so yeah I need to allow it to step up and to step down so that'll allow it to step up and down one block but it's not actually doing it not sure why it's not doing it not sure why it's not turning red that was the other question why is that not turning red can please foot it's left foot good and my foot is right foot good so can please foot is lying to us or something yeah what that that is see there it decides it can foot it fit it but then I'm testing with a bogus size so it barely makes it fit and then the bogus size fails and turns red but there it doesn't turn red and I don't know why that's a good returns one why why is that returning one oops I actually stepped in oh this is supposed to return false not true so again for some reason it's not returning false that returns true step in okay it claims it's what is the location dot z it's up in the air a little bit at 75 and z and 15 2048 okay claims that the foot it's just above the 75 boundary and claims that 75 is open and 74 is solid so it's just above the 75 boundary that the 74 blocking solid is a block you can stand on but it's clearly not I don't understand that why does it become invalid when it gets to there but it's not valid in the other place now it claims it's not standing above any ground okay now the path data is different it's in a different spot now it claims there's a hole underneath it so it's like it's looking at the wrong one here it's like this one is looking at the right side why can't I not double click on this okay I'm not working so if we break on the right foot 2047 we're testing 2048 it's well behaved okay what square are we looking at at zero y zero negative seven zero okay and then if we look at the left foot it should be a different thing step negative seven zero should be negative six zero is negative six zero but negative six zero and negative seven zero both have the same path data no they don't okay they are off by one so that's definitely has ground under it that definitely has ground under it it's like it's looking at the wrong spots but it is doing a search here it's actually doing the full search and then I guess it just never finds a good one and returns the default one but then why does that default one report valid well okay wait wait wait they seem to be reporting different z's but they're not rendering different z's all right so let's go to here let's see what the foot position is supposed to be left foot dot z right foot dot z okay this time the z left foot z is under is down why is that down there where did that come from z left is up where does that where did that negative value come from how did it get down to nine five seven five is this thing offsetting vertically other than the d z which is integral to intentionally avoid this problem no unless the polys have it you should all be oh wait but why are these these are just the left why are these different oh because it's because this is using the angle the tilt angle although the tilt angle should be zero don't even know what that is why is that not zero why is that upside down oh it's that's a warning sorry why is that not zero because I tilted with the camera okay right so I need an option to world space that doesn't do that so I need an option world space flat yep that's all it was all right see if that fixes it finally okay so now one of the things that happens is it's discontinuous with the other motion actually I think it's uh flipping which side it's on not positive let's only render one side yeah it's moving it to the wrong side the left foot is ending up on the right side makes these names seem backwards to me positive x should be on the right so I have some head bug there it's trying to lower the foot but not correctly still you can see it was down at the ground for a moment oh as I tilt the camera breaking so somebody is still using the camera tilt so somebody isn't using flat here it is why does it do that like once it moves the foot down there once and then bales okay so I've got that probably too far ahead just go back to this case not worry about the falling thing and make sure I how this looks why is too far and z is too short so that's to do tune the point five I believe wait they're the same why is one crazy and one reasonable something else is interfering with this oh I see that is the different ones just can't tell because they're not connected so now the thing is that it's still using the old ellipsoid animation or ellipsoid ellipse animation independent of where the foot placement turns out to be which is then just totally wrong I don't know what this number needs to be okay that's not too terrible slow mo you can see it's trying to step down but failing and then the problem is it only discovers it's stepping down right when it goes to do the placement so the animation isn't even close to being in the right spot and that's what we'll have to fix next uh after I fix left and right are not going out the same distance the left is jumping really far forward and the right is not oh it slows down when I look down I forgot about that I fix that too let's make the uh the feet different colored just so I can make sure I can tell what's going on and of course the right foot is on the left and the left foot is on the right because oh no it is the right well now it is doing some weirdness still the green foot is switching sides still why are they switching sides oh because I did all that logic just flip them but I didn't do it here now why did I do that thing to flip them I've already forgotten okay and then they're competing different spacings here the preferred spacing is 3.5 that's 3.5 or 0.35 in both cases and then centered and then z left now it seems consistent I'm not sure um so I'm going to answer to the question there's a ton of stuff in the chat so if you want me to answer a question you have to say at nothing's two at the beginning so I see it so why are those feet moving why are they not positioned sideways by the same amount 0.35 f is the preferred distance it's definitely moving yeah look at this how can those be different it could be different if the planted function is not returning original so first let's just return let's always return that maybe it's picking up place step far away from that for some reason no okay so we always pick poly zero the question is why is poly zero not at the about the same position as the other one so other one computes right here 0.35 f y left and this one computes negative point wait I did switch the signs this is what they need to be to be the same now they're still inconsistent all right uh that x plus x plus y plus y plus x plus y plus x plus y how does that come out different wine left is obviously different but the z's get adjusted but that's okay oh this doesn't no it does it is centered 0.0 how could that be different how could that be different I don't know wait this one is it that dang it somebody's trying it to zero is that's what it looks like 0.35 negative 0.35 0.35 there should be 0.35 0.35 negative 0.35 yep right is consistently negative 0.35 left is considered consistently positive 0.35 yep how is these different let's just make the left foot consistently compute the same thing no matter what and the right foot gets stuck oh the left foot gets stuck well yeah the right foot gets stuck yeah green is the right foot okay the left foot so left and right foot are backwards as I said in the code all right so that was semi-consistent so then the question is how does this path become inconsistent from this path so if we just copy this code up to here it should be consistent in both paths because it's computing the exact same thing in each path right the white one looks correct looks consistent so this is different from this even though the computation should be basically the same there's this tweak of the z left we add pos x pos y z left well we plus equal z left that'll make any difference oh wait it's not going to change anything because I still have this code running oh it's world space flat again made these flat so they were angle dependent all right okay now they're strangely centered ah they're not accounting for the rotation correctly because I deleted the wrong rotation in world space flat I used the wrong one I used the x rotation and deleted the z rotation and I meant to do the opposite where did that live yeah I'm supposed to do this one not that one or a cam but that's left over code you won't worry about it okay Jesus so now that should be back to what it was supposed to be so ever since we switched to world space flat that was broken okay good good good good good good good all right now it still can't do that down in the it still does not place the thing down okay so but now we're back to looking at why it doesn't place that thing down so we want the on-screen right foot which is in code left foot and we want to do this and see why why is it not trying to place it oh because I disabled that code now yeah yeah yeah yeah all right now let's see if you can do it it may still be working I don't know there we go so now it's trying to put the foot on the ground or it puts it onto the ledge if it can fit probably looks dumb to do that it's probably better to stick it down although if you can't so yeah I'll need to figure out how to prioritize it so that it prefers to go down by one and of course it can't go down by two so this Vectis needs to be weighted weight the downward distance less than the moving inward moving outward is okay moving inward is not okay something like that so let's change the range over which it's looking so it moves in less right so there you go that's the expected behavior it has to plant the foot all the way down there to get the thing to work and it will have to tilt the body and stuff to make that work and I'm not going to try to get that right type of Z right equals floor Z left and we weren't looking at what the left foot was doing so we won't we don't see that but okay and then stepping up I'm not sure I can trigger the stepping up because I as soon as I get close enough to trigger it it pushes the body up anyway okay and then let's put this back to what's the size it's testing with one five yeah okay so they match so it shouldn't ever turn red except when it's actually can't get when it can't find a place to put the foot like when it's falling or if you were over a 2d pole oh see it's managing to it has enough forward and backward range that it can either touch it to the back one or can touch it to the forward one okay so now we need to animate between this foot position the plant foot position and the animation position so let's check that in so now what we want to do is we want to do this computation of where we can plant the foot ahead of time so that we can animate to it one way to do that would be to just compute at every frame based on our current position velocity and be like where would we plant the foot if we could do it right now and because that will update continuously as we animate and then we smoothly animate the foot actual foot position to the desired foot position that will move continuously although it will kind of hurry and it's not really correct but the problem is if right when you're about to get there you go off an edge and it discontinuously changes where the ideal foot placement is that discontinuity will show up in the animation because you're nearly finished into the right spot of the animation so you really have to look ahead you have to say in uh and commit actually like if you turn right as the foot is about to go down you can't change your mind about the foot placement so you really do need to pick the foot placement in advance and then animate to it and in the same way you have to animate out of it so how do we want to do that i'm at five hours i think i might stop here so let's note what we want to do at this point so the things to do are look ahead okay when foot is halfway from previous position to next position compute placement for next position to animate foot from old position to halfway cleanly reanimate foot from halfway to next position cleanly four deal with stopping if foot placement was computed before stopping so there maybe you still want to continuously compute the new foot placement as you're animating to it and try to make adjustments to it you just need to not be discontinuous five i k legs two feet so i think that's what's left to do to get to that point of actually having the legs animate yeah like i said when i did this before i first i get the legs and then dealt with trying to get the feet placements right um and that probably would have been better because the i k it's a very stable sub problem that you solve once and it's not tweaky and stuff you have to it's a pain to get right but it's just math um and probably it would have been a better visual payoff to get the legs connecting the feet even though the feet were wrong and then work on getting the feet right instead of trying to get the feet right first but whatever um so yeah any questions i'll take questions before i shut down why don't you have any colorings check the fact on the left there's a video that explains my syntax highlighting style which does have color but not very much you do not prefer camel case naming i am use a mix of underscore base naming and camel case naming and uh just it's kind of a random hodgepodge um didn't the overgrowth guy give up on proxen animations i don't know his current thing but hit the game dev talk he did he was still doing procedural animation using about 12 keyframes so like the run has two keyframes and he procedurally animates between the two keyframes and still does all the i k stuff um there's a he has a good talk about it um you see vaults david rosen here's here's his current what his current stuff is and he talks about the using keyframes to do it but the whole point is that he procedurally animates between the the keyframes he like some of it uses like a sine function to to determine this how to blend between the two and another uses a spring damp spring oscillator to compute the weight to animate between the two are there any books you can recommend i'm an obvious program but i'd like to get as deep into as i can i don't have any books i can recommend um i'm i'm not a very good person to answer questions when you're a beginner um because i'm too far from that like the books didn't exist back when i was a beginner so i should probably make that that's an feqo too i should probably put that in the fact oops i typed planet instead of plant um i don't know what i touched in vain i guess i should cancel that yeah that was just good to do um let's not commit let's just push push before that commit that's pushed i like to commit it miss some earlier stuff but do you render each cube or do some math to combine relative relevant cubes together that's what stb voxel render does it only renders it produces a mesh that only has the faces between cubes that are facing the air and removes the faces between the cubes uh you're welcome still taking questions all right if i'm gonna get another question in the minute or so i'll stop how is working at looking glass studios was it a big studio no it was small by modern standards um you know we had maybe five programmers on a game and three or four artists and three or four designers something like that um it was a lot of very very smart people um who understand understood game design as an intellectual problem um could advance arguments for why to do game design things in particular ways so uh i don't know i don't know what to say about how it's working there i mean it's part of it's part of why i don't work at other studios is because it'll be hard to hit anywhere that says good but when ray tracing like checking for the ground how do you minimize the amount of triangles you compare to well for what i do i don't i mean i don't actually have a ray tracer but i don't compare against the triangles i just compare against the blocks so that you can skip trying to do the poly tests um so um so yeah i'm not actually doing stuff like pick the chunk that actors in and do that i actually am doing it a slow way it is this is why the path find is slow we talked about this when we did the pathfinding the pathfinding um uh for every it wants to test a box that the represents the player which may extend or the critter which may extend across multiple blocks horizontally um and so for each vertical column it queries the mesh cache and gets the the the physics cache um which has a explicit pathfinding cache that is one bit per block for pathfinding it's not good enough for physics um because of slopes although we don't handle those currently at all and um and it's inefficient because it's creating the cache for every column the physics stuff is actually smarter it acts as a physics database which can have different block types other they're currently not encoded in there and the physics doesn't account for them but the physics does a gather operation and says to a little subsystem get me all of the blocks in this 3d sub region you know like 8 by 8 by 8 region where it thinks the physics needs to do some searching it's not a full raycast it's just a little local search because physics you can only move so far in a single frame as that gather operation looks over the physics the pulls out which mesh chunks it needs to do doesn't access the mesh chunks multiple times it grabs each mesh chunk once it pulls out the data it needs out of it that data is actually compressed run length compressed so it has to d run length compress it and expands it and so then the physics system gets to work on these little chunks that are like 8 by 8 by 8 that surround the player or the object that's moving and is guaranteed to cover all the blocks it ever needs to know about and so that's just a dense chunk with no mesh cache or anything to worry about so that's how I isolate that to make it easier once you want to do a long raycast for like visibility we'll either have to use the AI database or use the physics database and we'll have to think about how to do that so that that query can run efficiently but I don't actually have one of those right now wow thank you I don't know what that was in reply to oh somebody I'm just going way back and I see that somebody mentioned that I left out of flat that's unfortunate I didn't see it I found it myself but yeah sorry I never checked the chat what's that reaper doing on your desktop do you make your own music yes I do make music it's nothing to shout home about so okay I answered the ray tracing thing played any games lately I started in plus plus I need to get on clockwork empires which I wrote scp connected components explicitly for clockwork empires which just came out on Friday or not Friday came out yesterday the day before yesterday came out Wednesday came out Thursday came out Wednesday or Thursday I remember which and somebody earlier asked can you play a song and the answer is no I'll just noodle while we're talking I'm on acoustic which I'm not as nimble on I'm not getting these strings down how does that go at that point I see how did I finger that people were uh but the note is there did you name him Garrett because of your surname no no if anything Garrett is probably an accidental rip off of uh it's a glen cook has a there's a series about a detective a fantasy detective named Garrett that might have been an accidental rip off by somebody I know you had a smiley on it anyway but hey how does that go I played that riff in a long time no it's not quite right I haven't heard it in a while I can't do this I'll make you stick that's enough oh sorry games um so yeah I mean I've the when I went into the game industry I started playing games a lot less often it's just one of those things pretty common not universal there are plenty of game developers who play lots and lots of games but it's pretty common to kind of be a little burned out or a little frustrated with the obvious laws once you've been inside it I've never thought about voxel planet generation where the voxels make up a spherical planet no I haven't really thought about it I know there's somebody else out there who did uh I can't remember the name of his blog he was doing a big write up on voxel different voxel ideas and he wanted to do that kind of thing first job as a coder wasn't gamedev right did you also did you study something or start working right after high school if I can ask um so I started learning basic in high school and then uh one summer I did volunteer work at the high school because our library book system was written in basic and they asked me to enhance it um I don't remember what the enhancement was it's a very long time ago so I did that then in college I then I went to college and I learned pascal in college very early that was the first language and eventually learned C and while I was still in college I took a job fixing somebody had a turbo pascal program it was a print shop so they printed you know they had a big press and or multiple presses and they did print shops and so they had a invoicing or whatever system in turbo pascal needed some enhancements or something I don't really remember so I that was my first paid programming job um I think it was turbo pascal seems likely and then I did uh some work for a professor as an undergrad uh with um measuring program complexity so I wrote a little parser see the C parser for that and then I went to work for a company that made software for printers not uh not printer drivers that run on computer but the firmware inside the print inside the printer itself and then I went to the game industry so I just went up a whole little string of of jobs I was always making games in basic in high school little simple games I never made anything complicated what do you have used on malloc failure and error return versus process termination when out of memory uh it depends on the application so in lots of applications um you can't do much once you're out of memory so it doesn't matter that much if you use the s to be erased stuff that I use all the time for my tools but probably should not be using on a shipping product those things when a realloc fails internally because it's a dynamic array and it's resizing the array and the resize fails it just puts a null and then you try to write into the null and the program will crash so whenever that stuff runs out of memory it's just going to crash um the uh my work the program I have at work um I actually wrote a system where it uses set jump long jump and basically throws an exception using set jump long jump um when memory allocations fail uh so so that could be a little more robust in the face of failure um without having to make each location explicitly check null but that turns out to not be that great um you still have to make sure you free everything else or that you stored it somewhere so that you can make sure you free it and I had had a trick to avoid that problem but it's still kind of clumsy and I think I would never do that in the future I wouldn't try to use an exception to handle out of memory I think it's better to just propagate the nulls out and everybody has to check for them and that's like any recommendations for algorithms that would be good to know for world generation other than the simplex noise for 2D gaming world no idea I'm not very good at procedural generation it's not one of my strengths it's why the world is really crappy in this game I've never experienced burnout absolutely uh and I don't have a good answer to what to do if you get burned out coda chrome go I was like I'm already here doing major so and there was not right do you prefer for coding something by yourself or as part of a team by myself um my when I'm on a team I think a small team would be okay but on generally on a team my productivity goes down because I have to communicate with others I have to follow other people's style rules I have to deal with their stuff and my productivity goes down and as a result my morale goes down uh and that can be a death spiral or it can just mean lower morale that was true at looking last definitely um but I hadn't hit the my full stride when I was looking at I hadn't learned yet what my full stride was what I could do by myself so it didn't I didn't miss it so much what was the longest you went without coding I don't know um not long because I I haven't been in a hospital where I couldn't code or anything that prevented me and I haven't like taken a camping trip with no computer or anything like that um I think whenever I went home I still always took a laptop for sorry when like went to for Christmas for a week or something I think I always had a laptop so I can always program so it's probably not more than like three or four days I don't have rad teammates I'm I control up a project at rad I'm the sole programmer on it it's not totally true Fabian has done some work on it but it's my my project I have to control over it so uh that's just how rad works generally so yeah I don't know for sure I would guess three or four days it might not even be that long you guys yeah I mean if I go obviously the working um you'd have if you were working you'd skip two days and depending on whether you're programmed in those two days but on a vacation obviously you could go longer but I don't think I've taken a vacation where I didn't program oh wait there's a I think all these streams need to end with guitar and everything now I think they always could a dream of a job where I can code on my own feels bad man yeah I'm lucky to be in this position when I started I mean learning c++ I never knew this you're working on a team not by yourself that's definitely normally true looking forward to handmade con no not exactly um you know uh Casey asked me if I could contribute on a certain thing and I said sure um I'm not exactly a fan of handmade con because um Casey feels like in normal con it's a lot of work for the presenters and uh an unreasonable amount of work given that they're not paid or anything and handmade con he seems to have gone 100% the other direction where there's no preparation and it's just him asking people stuff and I feel like that's maybe too far and a little bit of preparation would help the information density so I don't feel like handmade con really hits a sweet spot personally but that's me I'm not saying that's universally true I didn't even watch the original one I um you know I got the videos I looked at the videos and I kind of clicked through them really fast and it was like the the density of information was just too low I didn't bother for me again they're not aimed at me as much as they're aimed at you guys so I do what those other chords are in the street got to whoops totally screwed up the timing on that I need to tap my foot to get it right your admirers in the street got to whoot and stamp the beat in the heat from your physique as you twinkle by in Marcus's son sneakers that was just a little seven versus eight polymeter that's why I like that can you say what you're going to speak about or is that under wraps I don't know if it's under wraps or not so I'm not saying let's see give you another minute can I think of any other songs that I know how to play we ever programmed something to make music help you make it I have a little dumb project that I made yeah it's not gravy train but yeah we call it riding the gravy train uh come in here have a cigar yeah um have you ever prepared something to make music help you make it um I have written multiple things uh to help make music and I've written a program that generated music um that was just for a goofy side project a couple years ago for nano genmo national novel generation month that there was a spin-off national novel opera month national opera generation month something like that but I have a custom program that I wrote for writing orchestral music that I used to um be able to control the orchestral instruments better than the typical midi authoring that people do and that I used for the music for lost in the static to do seamos transitions in lost in the static between songs um how long have you been playing the guitar uh I guess I started around 16 so about 30 years I'm probably not much better than I was after three or four years uh I probably did not increase my skills very much since then because I don't like I don't do um you know uh shredding practice or anything like that so I don't really have increased skills I have better skills than I did then at recognizing stuff and figuring it out but in terms of nimbleness of fingers and stuff like that and I haven't been learning other people's music very much either so I don't have a lot of of songs learned other than what I learned back when I started here I have one song that I can finger pick and maybe we'll end with that if I can remember how to do this uh I screwed up I can't see the front of the single okay so many excuses see I'm used to doing this sitting and not up like this but because of the whole standing desk it's hard to and it just goes on like that and somebody's asking what that was see if I can find the link oops I had it I didn't get in my cut and paste buffer all right so that's it uh if there are last minute questions I'll answer them after talking with the stream all right so see you and bye