Observable Flutter #32: flame_behaviors

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome to another episode of observable flutter my name is CRA Benz I'm your host and today we're going to be exploring at last how to organize the sloppy code of zombie logic pathf finding and steering in my zombie shooter game built of course with flutter and Flame and the package that I'll be using for that today is none other than flame behaviors which was written by esteemed Community member and one time I think only one time uh observable flutter Gast wolfen so uh I'm excited to get into this I have not studied the package at all yet so I'll be learning from scratch with you all I have however been uh putting a little bit I'm trying to remember where I left this project two streams ago and it seems to be in something of an incoherence state so that is all some of the fun uh that we have to look forward to today but before we get too far into that folks remember this is the flutter Community let's do what we do best and be great to each other be warm and welcoming to everyone and uh you know certainly not overly critical of other Technologies and the like can anyone find my cursor oh there it is great okay lovely uh uh let's see here I do have one thing I need to check let's see content sorry folks little bit of uh oh yeah there we go okay all right everything seems to be in order um all right and uh yeah what Let's uh let's get started here so how's everybody doing today I've uh actually do have another thing or two I need to check before um before fully diving in my apologies okay I don't think chat is working is chat turned on missan um I don't know how to do this I'm gonna ask someone who helps me all right my apologies we're not off to the fastest start here but um all right let's get into it hopefully I'll uh hopefully we'll get chat turned on shortly and uh then you'll all be able to help me learn flame behaviors because I think I'm going to need it so uh as you can see actually the first thing I did a second ago was update the flame version and that didn't break anything so that was a simple migration uh and I did that because flame behaviors mentions that it requires a newer version of flame than I was using I hadn't updated since starting this project so it was long overdue so that's done and then I was also then I ran the game to make sure that it did in fact uh oh I think I oh no that was right oh yeah no it needs to be needs to be a version that actually exists um so I ran the game and remembered oh yeah uh Lucas and I who he was helping two streams ago last time I worked on this project we seem to have left this game in something of an irregular State because there is better performance when there's 100 zombies on the screen but they don't avoid each other anymore which was the behavior that uh made it slow so I hope we didn't make it fast by simply turning off the expensive feature uh but that I'm also going to spend just a second trying to remember so this is a PR of the changes that were made the last time I worked on this and I do yeah I remember us putting uh collisions in every zombie got their own hitbox whereas before I had like had this kind of irregular algorithm to have the zombies not step over each other and then clean up movement I think that was the method where so this is in on collision interesting yeah cleanup movement was supposed to prevent them from stepping on each other's space uh I think I may I think we maybe renamed it last week Because by the time on collision is called they've already moved that's why they're colliding so cleanup movement would need to like move them back which is what I'm guessing the oh yeah the intersection points and we didn't we ran out of time to actually analiz where the intersection points were and and clean I don't think clean up works because we're not passing in the intersection points or we are passing them in but I'm not using them I I I remember us not having time to make use of that okay well that's fine uh and I will just kind of carry on uh all right so flame behaviors let's see here um it's time to where's the documentation okay Collision detection event behaviors getting started well I'll read the getting started which I did read on stream a long time ago when I mentally queued up this package to play with uh on a stream but I haven't looked add since and basically don't remember anything okay so there you go you add it I'll do that so an entity is the thing that we need to know about the entity is the building block of a game it represents a visual game object that can hold multiple behaviors a zombie would be an entity and behaviors would be things like hunting the player not stepping on the toes of other zombies because they're very polite uh stuff like that which in turn Define how the entity behaves great so Define a custom entity by extending entity and then we pass the list of behaviors to the super Constructor great great and I'm guessing then I I I vaguely remember wondering about this aloud uh last time as well I'm guessing we attach an entity to a component which seems to be the next thing that this talks about so types of entities there are two the base entity is a generic thing that can be us represent any game object so potentially nonvisual as well or a positioned entity that is based on the position component great so these entities use the entity Mixon that provides base functionality for an entity if you I see okay these entities both of them okay interesting oh yeah so my Sprite entity extend Sprite component with entity mix in and then I guess there's also a position entity mix in maybe yeah because Sprite component is not a position component that's higher up I think uh or maybe not I don't remember these entities use the entity Mixon oh yeah that's what I just said uh if you want to turn any component into an entity you can use it for for instance if you want to turn a spread component you can do the following flame game can also have an entity great all right so then we get to Behavior Uh a behavior is a component that defines how an entity behaves oh I'm getting some feedback on chat can we enable it excuse me sorry folks uh I really want to get chat turned on because I want to say hi to you all hopefully that's coming soon uh Behavior a behavior is a component that defines how an entity behaves it can be attached to any component that uses the entity mix in so right right uh and handles a specific behavior behaviors can either be generic for any entity or they can be nicely tailored to a specific one Behavior composition each Behavior can have its own components uh components four can have its own components this word's confusing me uh have its own component components for adding oh I just can't read each Behavior can have its own components for adding extra functionality so behaviors can have more components oh yeah I remember having this remember this too I'm guessing that that component is not a flame component but I don't know and we'll find out I'm guessing this is a a component unique to this package so we can have entities and behaviors and then behaviors can have components we got this tree of things uh so for instance a timer component can help a behavior component do something at a certain interval looks good not a behavior is a nonvisual component the word component is getting heavily overloaded in this context uh describes how a visual component an entity behaves therefore a behavior cannot have its own behaviors okay yep I remember reading that what's next the following sections will show you how to use flame behaviors for common game development tasks like handling game input or Collision detection flame behaviors also have some conventions on how to name and organize your code naming conventions and code conventions I definitely want to look at those uh oh Bo Ando okay oh there's a video oh I wish I'd watched that ahead of time oh boy oh they made a way better pong than me okay main all right so let's see what we can deduce from this I don't see any flame behaviors Shenanigans going on yet in the flame game here from pong uh handle keyboard component has Collision detection on load yeah this all looks like generic flame um yeah one second here oh wait I think this might turn it on on anyone save right I think I just turned on chat can someone try to say something does chat exist now I'm gonna refresh this I have uh you might have to refresh the stream no I oh there it is hey all [Applause] right I found the check box it was under a menu that was hard to read while I was also talking hello everyone all right great um okay so creating the beh creating the paddle entity and its behaviors all right here we go so positioned entity interesting and so the children the position entity gets a child component and that's what draws the actual paddle and contains oh the hitbox is also a child of the entity and is not attached to the component uh by the way wolfen author of this package hello great to see you and I look forward to many snarky tips the snarkier the better uh all right so with Keys interesting uh oh this is going to bind how it's controlled I guess okay so here we have a behavior right right right right nice okay so this is also just really good design um so we have a spe special Constructor for this paddle class that basically turns a behav or it attaches a behavior so this moving Behavior attribute which is uh decided as required okay so that's a field yeah on this class I gu it's just omitted or I'm not seeing it um okay so the moving behavior is required on this positioned entity and the helper helpful const structures attach that appropriately uh love it yeah okay this is great this is nice now I'm guessing we're going to learn more about the keyboard moving Behavior as we scroll down so let's do that start by defining a paddle blah blah blah yep we just understood all of those Constructors looks good all right then there's the hitbox so one thing to note is that the paddle has a rectangle hitbox as one of its children which allows for Collision detection because the paddle does not have its own Collision behaviors we don't need to do anything else I guess that means because the logic of lighting lives in the ball class when we get to the ball entity yeah we showcase great all right moving Behavior this is what we're here for um uh happy to help it's a team it's a team effort out here right that's why we call it open source uh oh let's see uh Andrea said or Anda Andrea I'm not sure which uh I have a question why does flutter only work with material design the fact is that you can't build an app without using material design and my question is can you do it without material design so yeah this is worth talking about uh material design is kind of the default styling language in flutter that's true uh their the material library is built on top of the widgets library and the widgets library is kind of unstyled widgets but it's definitely true that there's a lot of functionality that lives in the material library that you know maybe in hindsite could have should have been put in the widgets Library it would make it easier to start from absolute scratch uh the goal of the material library is obviously it's opinionated out of the box which is different than like unstyled HTML uh the goal of the material library is to be customizable enough where you can still Tinker you know through the theme which is kind of like flutters CSS you can still Tinker with each individual control and change their color and their shape and whatnot until you achieve a look that is distinctly yours and doesn't have anything uh you know the fact that you're you kind of have this archaeological you know you're building on the ruins of another city like your styling is on top of material that shouldn't really be obvious or visible or detectable to end users that is the goal of flutters material implementation um and any feedback that you have as you pursue that is definitely welcome so that's what I would say to that um okay so moving Behavior as described above the moving behavior Can will be controlled by keyboard input that's great for we need to create a keyboard moving behavior. Dart file that will live in the behaviors directory all right so we're going to need I think we'll have the same kind of um code organization I'll make a behavior folder and we'll start putting some stuff in there so let's edit the file and add the following code here we go so it extends behavior of type paddle and paddle was the entity that it has to go on okay so behaviors are maybe optionally typed um has keyboard Handler has game ref that's interesting so these are like the these are classic flame things now I'm curious about the super class of behavior like is it also just a component um I'm gonna look at that shortly okay so this has oh they're just like other places to put like on key event is still just coming from keyboard Handler and update is the same method so this is Is this materially different than another component if I had just nested a component on the paddle wolfen that's my first question for you uh the behavior can have a parent type so it's parent property will be strongly typed yep that makes sense that's that would be coming from here and then uh the parent attribute yeah uh would be strongly typed that's great Jank hey welcome to the Stream um okay continuing down as we can see behavior is quite compact only has one goal move the thing up and down when pressed that's great creating the ball entity and its behaviors okay looks good so here we have another positioned entity [Music] um and this is yeah I'm oh man I'm so curious I I just I need to check out the library I want to look at these class is uh flame Behavior GitHub I'm going to clone this come to Papa where is my terminal here we go uh Dev get I don't think I have Mak very good open that's not I spell very good open source very good open Source CD into that and get clone flame behaviors the behavior is a component so you can compose existing components into behaviors assuming they bring a behavioral aspect to the behavior interesting code um flame behaviors all right this I think will help I'm going to move this back in the other window and yeah get out of here dock run Dart Pub get and maybe it's flutter Pub kit this probably depends on flutter all right so we've got behaviors and Flame steering behaviors oh that's a separate package okay I wonder if this is going to give us a bunch of offthe shelf helpers but first we're just looking at base flame behaviors and what is entity. Dart here we go this is going to be good I think uh oh right CD packages flame behaviors yeah we do have to be in an actual flutter package directory to run that now don't we okay so Mixon entity mixing on component so entities will always be components and this is coming straight from flame that's lovely and let's see what else uh I'm going to Let's kind of look at this real quick here so find behavior is oh find behaviors that just looks at all the behaviors and then what is this aware type T interesting okay okay so we can ask for just a certain set of our behaviors I guess Returns the list behaviors with a given type okay that's good um oh that's interesting I'm guessing this means if we can return just certain types of our behaviors that the idea is that the developer doesn't need to worry about how to organize their how they attach all their behaviors to an entity um because you can just pull them out in a you can pull out the ones that you need at a given moment and that that makes sense I'm still curious about the ordering of these behaviors and how that kind of gets thought about um whoa I've never seen this before very good packages oh very good packages get- R Works recursively w okay yes exactly you can look them up from the flame component tree great yeah and then you so you pull out the ones you need or we can get a single one so how does this work Returns the first Behavior found in a given type okay so probably only use this if you know you only have one uh this will return only return to behavior that has a completed life cycle AKA it is fully mounted great and then oh so you you best know that you have one because if you ain't got one you dble yeah because it's not returning a nullable thing so that makes sense and then the next one has behavior that checks uh can also of course then use that before calling fine Behavior that's interesting to do that instead of just have this have fine Behavior return a nullable one the different design API design patterns available to us all okay yes entities are components and the entity class itself has its own mix great and so super. children these are of course the children components so an entity is a component great uh priority key yeah it's interesting that it's only these yeah so you wouldn't use it super flexibly with just any component I mean the the Constructor only takes these things but I guess that's probably what the positioned entity is for and I'll take the other uh other things oh and then the doc showed us how to make an entity to extend like a Sprite component so that must be how this all works um oh the order is based on priority of value from Flames components was that factored into the find behaviors oh maybe it's tucked in this nope is is priority uh oh maybe there there was like a register children register Behavior if behavior is equals no oh where do we add a behavior maybe they get inserted in order at at the moment when a behavior is added it's tucked into the children's system yes okay great all righty so oh and then here's our position dentity and this has yeah all the other parameters that we would expect and then what special things do you do you have behaviors we assert that children wait behaviors cannot be added to I presume we need the word positioned entity here uh cannot be added to positioned entity as a child directly uh oh I'm thinking no I'm not really sure why this is happening because children is being passed up so we this Constructor can trust the fact that children wear type Behavior oh I see I get it you have to add behaviors in the behavior way and you can't add them as children type safety wise that would work which is why there's this assertion to check got it got it and then if behaviors don't equal null add them all oh add all this must right that's the same method that a component has so it must let's see where this goes add all it's still just adding compon all right now I'm really confused add all adds these behaviors well add all takes components normally and it adds them just like children would be added you know what actually I don't children uh let me I actually don't think I have this fully straight in my head yet yeah so children is behaviors children is children also where just like extra components go if you call ad on a component let's check this out I can't remember component so where's the ad method this says ADD child and children yes okay so this same list of children stores all all of our components and behaviors so behaviors are just kind of nestled right in there next to children I think I'm getting that right but then I'm not entirely sure why because at all it's not doing is it doing something special we're we're immediately in flame here this is just adding these behaviors like normals I'm actually not sure why this code is required and I i' uh wolen says children uh contains components including behaviors yeah that's what I just concluded s that's good the reason that we have this on the Constructor is uh for a clear readable so it's so the user can easily distinguish what's going on but what I can't quite tell is is there actually a behavioral difference sometimes it's as simple as it just is what it is okay all right uh all right back to the code tree so now let's look at what's the name of this folder oh in Behavior so this is probably just the barrel file oh no it's not what all right so behavior is its own thing um behavior is a component that defines how an entity behaves yeah so we read this on the docs Behavior can have its own components for adding functionality however cannot have its own behaviors all right so Behavior has a parent type that extends entity mexin that makes sense and it ex the par the behavior itself is also a component which I think I saw earlier and had was kind of losing track of but that makes sense because it sits it it intersperses itself with the children um there is no difference but if we ever want it it won't be a breaking change okay okay so add a component behaviors can't have entities uh so this is these rules that we have contains Point contains local Point okay so Behavior doesn't have much on its own but there was a [Music] behaviors uh behaviors plural oh that was the barrel file never have a brain try to do string matching because you'll fail all right the so Collision Behavior this will be an interesting one right out of the gate this could be how I start to have the zombies not step on each other again so this behavior is used for collision between entities the propagating Collision Behavior propagates the Collision uh to this Behavior if that entity is colliding with the parent if the entity that is colliding with the parent is an instance of collider okay I'm going to read that again uh the propag so propagates a collision to this Behavior if the entity that is colliding with the parent is an instance of of collider I I don't know what that is what is collider oh it's the type on the behavior got it got it all of these non one letter types are both better than one letter types and confusing because I'm used to really unhelpful one letter type so there's collider and parent right that that all makes sense and then it attaches to the parent looks good all right so we've got uh we determine are we colliding with the correct thing and on collision on collision start blah blah blah and this right is abstract so we can Define these methods ourselves all right I think I'm about ready to get started here and then there's the behavior un Mount unload so we attach these call backs on collision fine entity on collision super on collision okay all right let's start writing stuff reading comprehension is my greatest skill you may be surprised to learn that I have poor reading comprehension um let's do it in the words of Rafiki from the Lion King it is time so let's add a dependency flame behaviors oh the big 1.0 no bug fixes necessary that's a flex to just be sitting on 1.0 I'm sorry that I ship a perfect package that had no issues H that's so awkward hate when I do that I've never done that I don't know what that's like but wolfen apparently did um okay I don't really know how to do this yet but let's find out flame behaviors and I guess I can get rid of some stale Imports oh boy oh boy uh the first thing that we could do here is peek at the cleanup movement method which apparently wasn't doing anything because this is the code that I think we're going to have to bring or I could so there's two interesting three interesting things that a zombie does it alternates between a state of tracking the user and wandering based on whether or not it is close enough to the user that's the first and most primitive thing the zombie does then it has another Behavior Uh Oh then it as it wander as it walks it like veers and stumbles that's another thing that could be moved into the behavior system and then the third thing is not stepping like colliding with other zombies not stepping on the same SP space so any of those three things are potential candidates for migration to um oh wait you would recommend reading the Collision docs to make sense of this okay back to the docs any of those three things could be candidates oh wait I was looking at the oh docs or code I guess docs huh or where is that documentation here Collision detection oh yeah I don't think I've actually looked at this file yet okay Collision detection boom flame comes with a powerful built in system but the API isn't strongly typed components always get the colliding component as a position component and developers need to manually check what type of class it is that's true flame behaviors is all about enforcing a strongly typed API it provides a special behavior called Collision behavior that describes the type of entity being targeted for Collision it does not however do any real Collision detection you so we're just filtering the results from the global system that is done by the propagating Collision Behavior what propagating Collision Behavior does real Collision detection I assume the real Collision detection would continue happen in the core flame stuff I'm I'm suspicious of my understanding of this sentence again with the reading comprehension the propagating Collision Behavior handles the Collision detection by registering a hitbox on the parent entity okay that's what it means so it it registers itself for Flames actual Collision detection uh when that hitbox has a collision the propagating Collision Behavior checks if the component that the parent entity is colliding with contains the target entity type entity type which is actually what I said the first time uh specified in Collision Behavior so this means that a collision Behavior can say like like we'd attach this Collision Behavior to a zombie and it would register that it's colliding with uh other zombies oh I'm blocking some of the words oh maybe I can just be like really tiny living space look at me I'm still blocking some of the words but less uh so there are two main benefits of letting the propagating Collision Behavior handle Collision detection the first and most important one is performance wow by only registering Collision callbacks on the entities themselves the Collision detection system does not have to go through any collidable behaviors for which there could be many per entity we only do that now if we confirm a collision has happened it's not obvious to me how this would be materially more performant uh so I look forward to learning more about that uh oh oh oh yeah no wolfin is not behaving that's not in his DNA uh so Zip Zap Zoom oh hey a little uh you don't happen to do improv do you um so what I'm imagining is happening is that the core Collision detection of like which hitboxes are overlapping with other hit boxes that logic is still happening in flame proper and then in the old world when two Collision dete when two objects two hit boxes are overlapping each of their callbacks gets poked and then in those callbacks you might do something like say you know if the other thing is the type that I want then proceed with this new logic uh and this system sounds like it's going to replace that a bit but when we looked at its code we saw things like uh is this you know just a similar type check so and then if this type check passes then you're going to Bubble down into all the callbacks and that sounds like the same thing so I'm curious about where the performance improvements are coming from but we'll continue on uh oh that is an interesting question SCA the 90s music style well happy to have you in the chat um a style of music asks is flutter a sufficient language so framework of course you mean right Dart is the language uh but is flutter sufficient technology to create a very large application such as Instagram or Facebook yeah definitely uh Google makes many of its own large scale apps with it and those are pretty large scale so yes um like Google Earth that one uh recently released in flut pretty exciting YouTube create a very very featur rich very uh not just down the-middle app also made in flutter so yeah definitely those the two most recent that I can think of okay back to propagating Collision Behavior and the performance increase that I am not fully understanding yet um by only registering the callbacks yeah doesn't have to go through any collidable behaviors I guess I don't know exactly what this means and that could be where it's coming from uh for which there could be many per entity I was assuming these are like the logic that you run in your on collision call back after you perform a type check but I don't know uh we only do that now if we confirm a collision has happened yeah that's that sounds similar to what we do before wolfen please enlighten me uh the second benefit is that it allows for separation of concerns this one certainly makes sense you write code dedicated to a specific thing in a specific place and it doesn't have to muddy up everything else each Collision Behavior handles a specific Collision use case and ensures that the developer does not have to write a bunch of if statements in one big method to figure out what it is colliding with this part makes super obvious sense to me uh good use case of this Collision Behavior pattern can be seen in the example where we have a propagating Collision behavior that has its own hitbox uh wait my entity Collision Behavior so my colliding entity so this is what so it's attached to the parent and it's waiting until the parent runs into a my colliding and then we put the logic on them here oh my Collision Behavior sits right next to the propagating Collision Behavior I would I kind of assumed that this would be a parent situation behaviors can't have other behaviors so I guess that wasn't going to be the case but uh I'm still not totally sure how these all talk to each other this is interesting um here we have a where we have a typo there that's okay your code was perfect so the documentation is allowed to have typos uh this part I would like to understand better which I guess we can just look at the propagating Collision Behavior class all right I am going to do that although I'm also suspicious that I just want to start with the two um I want to start with like super arbitrary behavior and see how that works not just collisions so the wandering versus chasing but I want to also look at the propagating Collision Behavior I want to see how this works so it is used for collision between entities it propagates I already read this but I'm going to read it again it propagates the Collision to oh no I'm looking at the wrong thing it was further down in the same class got it this behavior is used to handle collisions between entities and propagates the Collision through to any Collision behaviors that are attached to the entity so I guess it can just call like parent do what was that children there was some something that like grabbed all the children of a certain type so it could say parent. find behaviors uh the Collision behaviors are filtered by Collision behavior. is valid which is the type check which is what the rest of the sentence says um and then you call on collision yeah if that makes sense so this allows for strongly typed Collision detection without having to add multiple Collision behaviors for different types of entities without having to add multiple Collision behaviors for different types of entities or adding more logic to a single Collision detection having multiple Collision behaviors for different types of entities I don't fully understand this multiple Collision behaviors for different types of entities I guess I mean you would potentially you would still add those to the component but they're just not going to be in this class I'm not sure what this sentence means um if you have an entity that does not require any Collision behaviors of its own you can just add the hitbox directly to the entity's children if you have an entity yeah so that was like what we saw the paddle because the ball took care of reacting to a collision any other entity that has a collision behavior for that entity will then be able to collide with it yep exactly so the paddle was able to be collided with by the ball so note this Behavior can also be used for collisions between entities and non-entity components by passing the components type to collider right because entities are also components so the parent to which this behavior is added should be a position component that uses the entity mix in okay flame behaviors come with the positioned which does exactly that but any kind of position component will work all right so last thing no not the last thing oh hey there was a comment on performance so the performance is that instead of having the checks happen in multiple behaviors it just happens in the propagation Behavior is and that leads to a big performance Improvement so the checks instead of happening M just happens in the propagation Behavior huh interesting all right I am going to uh return to my previous size I wasn't even in my final form all right zombie time all that Collision detection stuff was fun and I hope to get to it but to get my feet wet I which is an interesting idiom I'm going to get in the pool slowly I am going to try to find the yeah like CH oh zombie goal State yeah where do you get switched here um so in the update method we call update State what does that do oh this is where okay so update State yeah I this method should have been called like goal state so this is the logic that I first want to convert to behaviors and what it does is it figures out what is the path to the player and then there's a maximum distance and if you are under that maximum distance you start wandering if you are over that maximum distance you start chasing and set state to wander is a method because not only does it assign that value but it does whatever the heck else but like um yeah Z zombies you know don't they stumble around they get lost they're not good at their jobs and so this is like some random noise code to make that happen all right so I am going to add a goal State behavior and I'm going to add a new file I mean folder one of those words that start with f called behaviors do that isn't what I wanted to do let's try again uh I wanted to add a folder called behaviors and and now I can move behaviors into that folder behaviors and in here uh because Barrel files are so fun let's export uh zombie goal behavior. Dart and this will be zombie go behavior. Dart wundabar and now in the zombie class we can can import uh zombies behaviors behaviors great we'll alphabetize this goes there all right so this is not going to be a positioned entity so I think if I have a class it's a zombie goal entity should I first convert my whole zombie to an entity so I can attach behaviors to it or can I attach behaviors straight to components I don't think so I think I have to convert it the zombie itself has to be uh an entity right actually I guess we can just look at the behavior class that will tell us so Behavior again parent has to extend entity mixing which the zombie does not yet so that's the first thing we have to do oh I'll never find the zombie file in the flame behaviors package now will I okay so zombie extends position component let's try to convert this to a positioned entity and change nothing else and I think class declaration must have a body indeed all right that may have not broken it yes believe that is to answer the question do I have to convert the zombie into an entity and I think the game is still going to run which is great h package was meant to be a you can add it to existing games type of package and here I am adding it to an existing game okay didn't break added it good job successfully done which reward would you accept uh so now I need to oh so this means that it's not the zombie goal entity anymore it would just be the Zombie Go [Music] Behavior but that's going to have to extend is it Behavior mix in or just Behavior itself so it extends Behavior and the parent is going to be uh so you are going to extend behavior and that is going to come from flame behaviors and the type of this is going to be a zie and for that we have to import the game well that didn't work name zombie isn't a type well then why did you let me import this file to fix that problem what are you talking about it's literally right there oh okay ID was just slow [Music] um oh there's more reading to do I'm getting uh more homework all right we should read up on the naming conventions so your behavior names are not feeling out of place because zombie goal is not a behavior is it uh yeah I mean I want it to be a behavior unless I don't understand the unless I I think the package is more broad than it is um I want to move the goal Behavior off of the zombie itself and into this class but let's yeah let's read the naming conventions wait was that there did I see it no oh conventions coding and naming all right now this is some high quality documentation okay following name conventions are simply recommended indeed okay good player extends entity enemy bullet yes putting entity on the thing bad great Behavior action ver verb plus Behavior so jumping Behavior good jump Behavior bad okay I'm not doing that yet well let's look at some coding conventions entities should not contain any behavioral logic instead they should be composed of behavor behaviors sounds good this allows for more flexible and reusable code entities should not do any direct rendering instead they should add child components to handle the visualization of the entity wo I am not doing that yet oh yeah okay so I see all right zombie goal oh I clicked the wrong one because you typed more um zombie go bad moving to goal good okay um that's fair so instead of zombie goal Behavior this will be like uh goal seeking Behavior how about that and then I'll move the zombie go State enum into here how about them apples now the positioned entity takes a Behavior's iterable which would go in the super behaviors so here we will Begin by instantiating a goal seeking behavior and I'll rename the file too goal seeking Behavior you love that save the barrel file goal seeking Behavior oh yeah it was never in doubt so now we have an update method that we can call which gets a DT we should call the super update I think oh yeah the lter says don't override and do nothing Fair Fair request so now actually you know what we're going to go back to one zombie and I just gonna watch this print something every every whatever so uh 100 100 zombies where you [Music] at oh I'm not in the right file how did I not open I thought I opened the world here we go zombies Tad one run the game make the game happen uh yeah very high quality documentation except for minor typos how dare wolfen have the occasional typo in his second language just abysmal oh yeah I forgot to put anything in the class here print seeking oh man my editor is really uh just struggling okay reload Visual Studio would like to do the thing that you just asked it to do uh hey all right so we just yeah it's component we have an update thing this is great my computer does not oh did I make these assets no these are from Kenny NL a great uh resource it's like what is what is even happening in the universe right now what is going on okay didn't I type kenny. NL and then that didn't load it it went to some other website I don't understand why every time I just type Kenny do oh I don't think I put the extra e there maybe kenny. NL is this what I typed anyway it's from there they're great super good love them uh yeah made by Kenny okay so you're telling me that again when a human brain can't string match then you get into problems we've got a seeking intensify zombie okay here we go let's get some of this Behavior out of the zombie which is been the most poorly coded class in this game for an extremely long time I don't know if splitting the code this way is going to be useful or not uh we'll find out please tell me if you find this to be less readable obviously I'm covering ing a bunch on the right so this no I already hate it it's the worst I've never I've never hated anything more okay so update State this was the method get out of here just go away uh update State I suppose it kind of makes sense to yeah I'll just make I'll bring out the whole file or the whole function so update state there's going to be a lot of refactoring I think just to get this to work um right like all of this stuff isn't known so parent this would be parent. position and if we added has game ref to this then we could say uh with has game ref which I'll have to import okay that works now why do you not realize oh because it doesn't know the type of the game so that was like zombie game okay that's good and then line we can just import that I'll import all the utilities I don't remember what the other ones are uh maximum follow distance that would of course be a constant that we move to this Behavior so maximum follow distance looks good World tile size this comes from some con inst file all right goal state so that was a parameter right there that's obviously going to come off of the zombie itself and what what are the other issues oh set state to wander that's a method that needs to [Music] move wonderful nothing here works so wander [Music] path was a vector two that will go here oh yeah know we got to keep grabbing things so get random wander path that method can obviously move oh this zombie class gonna get real small we'll import random I mean import math and then I guess instantiate a random thing I don't actually care just doing this for now okay uh set state to wander all right so here yeah I'm going to worry about this later like when this was called elsewhere like an onload here I guess that would just be an onload of the new thing yeah all the all the references to this update date I'm pretty sure we can just get rid of that I'll we'll worry about pulling out later um wander started at that was also a I bet we can just grab all of these huh okay random again and wander length nice zombie class getting much smaller and a more contained place for the wander logic now exists now I'd also like oh wait so the the the documentation said don't have the entity render itself instead have it add extra components uh wolfen in your opinion onload what's happening here onload so I'm adding Sprites like this directly to the entity is that enough of a separation in your mind or would you add another component that is like the zombie Sprite component and handles this and um it's further separated because well I'm just curious which one you would recommend but I'll I'll worry about actually fixing that after we get your answer okay so the the behavior class now works or well it oh we didn't have to oh no we do have we have to call update State that'll end up being pretty important now won't it it's interesting that updates oh yeah right right okay so I was thinking why does an update State take the Delta time but yeah no it just doesn't use it all it cares about is the distance okay um so let's fix the problems in the zombie class the first one of which is here so set to wander that's a function that we moved into the behavior so what makes the most sense here we're in on load so my naive thought would be to call in the entity class we saw the method find behaviors and then there was the singular find Behavior so I don't know if this is what we want but goal seeking Behavior Uh Dot and then here we just call set to wander but but like this seems I'm suspicious that this is a bad pattern uh regarding the previous question wolfin says in general I would choose to do it in a component but it's up to you I often have a render component for that stuff yeah okay so that'll be a stretch goal does are are you crying when you read this or is this what you what I should do um it feels like why don't know yes it was an A or B question well no I guess I said are you crying when you read this so maybe yes you're crying or yes this is what I'm supposed to do uh if that isn't onload you can just do it in onload of the behavior touche but I think this question is going to still come up again later like if two behaviors need to talk to each other um override void on load all right what's the next problem so in the wander method we refer to a bunch of stuff from that so let's look at where this wander method is called because this is yeah right so in the update method of the oh I don't uh should I have Chase stuff in there as well yeah I guess I should I mean I guess it's seems like all of this is all just going to move to the update method here and then the wander method is going to move in and the chase method will also move in um apply movement oh yeah now this is where we're getting into the code that I really didn't like before I'm quickly moving all of my logic into this class this is just going to like take over the entire zombie class and then the goal-seeking behavior class is going to be bad um so I think I I don't want to move these in here I think I just want to set the state and then uh yeah that's what I want to do I'm just going to set the state so I'm gonna I've got update that's fine set state to wander that's fine get random wander path that's fine and then this code I don't think I want to put in here because this is acting on the goal Behavior but I am only driving the goal Behavior so now we're getting back to the question that I had earlier how should I think about something like this find Behavior goal seeking Behavior do goal state are you crying now so you'd have three behaviors a Wandering a Chase behavior and then a behavior that controls what happens okay that makes sense to me um this be this class is about to sound like a an abusive boyfriend or something because it's going to be like goal-seeking controlling Behavior I like get a load of yourself all right you don't have to be such a control freak goal seeking controlling Behavior or just goal control Behavior still very very toxic name do not do not date this guy let me tell you what okay so that uh yes yeah I was separation of concerns is not equal moving over code uh that is what I was just realized I was moving over all the code like no this this ain't it um and so should if we have a Chase behavior and a wander Behavior should they each like short circuit if they detect that the goal state is not their own so like in this goal-seeking Behavior CL or file if I have a few other classes so I'll just grab class definition so we had the controlling behavior and now let's have the um seeking behavior and then we'll also have the wandering behavior and in so wander is going to move to the wander method right this is going to you're going to go here and oh they should be added and removed from the child entity depending on the state [Music] oh okay that's wonderful that's just great so the update method of the wandering behavior is going to call wander and it's going to pass the DT and then we'll move over these wandering Fields they're hiding somewhere oh I had already put it on the game controlling Behavior yeah okay so set state to wander that feels like it should also beyond the wandering Behavior one day I'm G to figure this out yes yes yes yes yes wolfin you beautiful beautiful man so all the wander things are here set state to wander will also be called here now we don't actually have to store the gold State anymore because it's just which thing is so we may not need the enum interesting um when behaviors are added in removed is they like Ping ponging in and out of the game does on load get called every time they're added I'm hoping yes uh because if so then set state to wander could just be called in the wandering behaviors on load method and oh I still have to figure out apply movement oh boy that's going to be things were so coupled before this all started all right so update state right so I think what this is going to do now instead of doing this we can say uh we want to add the wandering oh on Mount gets called every time on load only gets called once great uh State could be on the entity as that is a common thing so would do you think it makes sense to continue to have that value on The Entity or could it just be the presence of the entities I guess it'll be simpler to have on the entity then we won't have to like look up whether or not uh a certain behavior is attached oh yeah you now goal controlling behavior and then we we're going to have zombie goal State goal state did I just delet it out of here I commented it out okay there we go lot of surgery left to get done here so what we can do now still in this toggle method would you do you think it makes sense to have let me read this question that I think is maybe going to answer the switching of State Behavior should probably be on the entity as you can set it to wandering and if the behavior yeah yeah that's exactly what I was just gonna ask okay so this would be uh parent. set state to wander but it's going to do different stuff than the other one did also I do need to quickly go back down to that and switch this to on Mount and do we have to call super. on Mount yep so set state to wander here is actually doing the stuff no I'm looking at the wrong method like a genius get random wander path where's that one I'm all over the place folks I hope this is slightly coherent so set state to wander there's going to be that method on the behavior itself and then another one on the entity I think that does make sense so set state to wander can say like if and then what was it uh has Behavior right so if has behavior of the Chase be what do we call it seeking Behavior oh no it's called Chase not seek what am I even talking about so if you have a Chase Behavior then how do we remove a Behavior Uh is there a remove hey don't get too proud of yourself everyone's 10 steps ahead of me chasing oh yeah all right all right all right chasing Behavior Uh how do I remove one remove oh it's just in the children so I would call the remove method remove uh oh but you have to like pass that an instance I don't have do I have to store should I store the instance of it somewhere because I don't have it yet I mean I guess we can get it oh that feels a little awkward Maybe not maybe that's what you're supposed to do find behavior is this what I want oh now it's chasing is this what I want find Behavior returns a nullable instance I thought it I don't think it does it says if no behavior is found it will throw a state error okay uh used to apparently so since state to wander so we remove the other one and then we basically just have the opposite one here so if you do don't have the behavior then we add a new and this of course is going to be uh wandering Behavior we add a Wandering Behavior I'd probably also want like some asserts because if I well it depends if I want this method to be item potent or not right you could decide you could set this up you call this method every frame you just don't care or it could be like you've decided you only call it when you're switching and then and it would be really weird if you you know didn't have this already but that's for another day so set state to wander this is set state to chase saying I guess we can do um do wandering and then I need change that method when I called it here set state to wandering okay so set state to chasing so if we have the wandering Behavior we remove it and we add it down there so if we have a Wandering Behavior we remove it and we if we don't have a chasing we add chasing um okay confirmed that this is how we want to toggle the existence of behaviors V okay this is going to be more organized I hope so the zombie that's looking good um what's my next thing here so in update state of yeah this was goal controlling we need another method here I didn't set the uh the uh the flag which it doesn't seem like we need I don't I don't know if we need it I'm not going to set it yet so here we'd have parent. set state to chasing then uh we already had this set state to wander method and that's called an on Mount so this actually changes the state of the parent so set state to wander I think this will be called now like initial iiz uh wandering state or something initialize wandering State and oh yeah yeah yeah so the idea here in the in the kind of on tick wander method it it veers for a bit and then it resets how kind of aant it's walking so that's why this is getting called again all right then we still have this the actual movement code going on in here that's going to get moved out into another behavior for sure and this is also where I'm going to be curious about uh like the behaviors are going to be dependent on each other right the movement behavior for the zombie is going to need to know about its wander path and just maybe there's no way around that or maybe that means I'm still not fully thinking with portals what are my other red lines so find the goal State aha yeah so in theory we're not going to need this because the behaviors are going to call wander or call Chase so I think we can get rid of this um and then the chase method is is there an unmount because this code of clearing out wander stuff in the chase method is like insanely awful uh but it still needs to happen I presume so I'm wondering if there is an unmount that I can put in the wanding behavior yeah that's in here so how about void on Dismount no uh let's look it h oops get back here uh Mount is there oh removed is there a method for that on remove oh yeah no so I wanted to do some cleanups St if you remove a child and recreate it doesn't matter on remove thank you isn't it nice folks I think I'm currently living in the future where llms who are like fluent with the documentation are conversational with you and you just ask them what's the method I need to call and right now wolfin is my personal llm thank you may the ones and zeros in your brain stay forever aligned uh this is really helpful and I don't know how anyone codes without the author of the packages that they're using uh on a phone call with them answering questions in real time this is great uh void on remove override presumably okay so now we just just saw this behavior for this logic that needs to happen here I presume oh wait you were talking about destroying and adding a new one right so this whole thing I just did is pointless because I'm not reusing the object so wander path and wander Delta degrees just get destroyed by the garbage collector and then I make a new wandering Behavior so this made this was totally irrelevant okay yeah it's pointless great uh this does support the theory that I'm not a single person but either an AI or multiple people there's a super great book what was that called Blind sight I think that has uh blind sight book yeah it's like in an open Commons book you can just get it for free I'm pretty sure I can't read so I got it on uh Amazon or on Audible and had someone read it to me but it this is a super fun book about first Contact and it's fairly it's super transhumanist and there is a character in it with uh who is multiple characters so everyone should read that okay so this Chase method needs to move to the chasing Behavior class and then update is going to call Chase this really just keeps sounding like I'm doing some banking or something um oh Chase doesn't take the Delta time oh it does it just also takes the line the path to player path to player yeah isn't that um like kind of trivially calculated but where do I do it there we go PA to player I guess you don't really need to take the path to player anymore you can just deduce it yourself and the position here is the parent position and we have more methods to do that's great [Music] so nice yeah this whole what did this do cash movement this Frame set from position to subl last position oh yeah that was for um that was performance stuff from last week that will be interesting to carry forward um game of the year yeah well I got a couple days left so also the game totally stinks other than that it's probably a great Contender for Game of the Year how hilariously broken will the game be if I were to run it now uh and it would compile no it wouldn't compile oh that's right there were a ton of red lines in the uh in the behaviors file okay apply Veer to path let's look at that method wow just terrible holy smokes this is going to force thinking about uh code organization in a way that I was not doing before and I was just slopping all of my pig feed into the same bucket it was not good yeah I almost want like a veering behavior as well as opposed to just chasing like I I I need to rethink movement on this zombie so holistically because veing I mean maybe veering is just how the zombie chases so it does belong here I guess I'll start by putting it here and then maybe further organization will reveal itself uh yeah a package about code organiz or organizing is making me think about organizing code that's crazy uh Allan Source I don't know if that's how you intend it could be Allen I'm going with Allen's Source Allen Source uh I'm glad you're enjoying it welcome so I think I'm going to try to keep uh I'm just going to keep veering stuff in the chasing Behavior behavior for now that was a good sentence and worry about it later so verer started at needs to all right so probably all of these ve oh yeah there was like lurching oh boy oh boy uh these will go up top thank you thank you debug pathf finding see what I really want I really let me tell you what I really really want anyone in their 30s who's alive in the 90s knows that I just evoked one of the alltime classic songs so people sometimes know songs that were written before they were born so maybe anyone knows what I'm goofing around about but what I really really want is to have this like movement object which could be as simple as Vector 2 that is kind of passed through a series of modifiers and so first there's the uh and and the the behavior is not being able to be nested is oh we got one all right great everyone knows the song Wonderful uh this is what I really really want I want a movement representation which is maybe just a vector two that is kind of passed through a series of modifiers and because right now again this Chase modifier is still just like going to contain a lot of the ugliness that used to be in zombie and that will be a little better in that it will be separated out from the rest of the ugliness I guess I'll start with that and then fixing the chase chasing Behavior class will just be the next goal we'll do this in bite-sized chunks I think I just cut some code that I yet need to paste I did paste it so you're saying then that value which I'm guessing you mean is the movement Vector that would get passed around to all the behaviors uh that could live on the entity and that is how flame steering Behavior does it all right okay well first once I understand this then that'll be maybe what I do next I'm going to finish this refactor only got 28 minutes left in theory this is just a matter of copying over a bunch of bad code and then watching it run from a different place so I think I can get it done and then maybe in the next stream we'll convert it again to steering and I'll stop initializing new random classes at some point in the future but not today all right there's more red everywhere oh there's one down here what do you oh yeah know I'm still waiting on those oh okay Move Along path oh gosh this is so nasty so debug um yeah so debug here uh that'll go on the behavior I don't even know if this makes an ounce of sense like literally any sense to put because debug was to render stuff or not no we're not putting it here this is just crazy talk I'm G to comment out debug pathf finding and figure out what to do with that later so debug pathf finding okay now we're just down to the moving methods Move Along path and apply movement and apply Lurch I think that needs to be its own behavior so I'm going to have a new one that is moving Behavior dot art and I'm going to grab some stuff and it's going to be moving behav moving behavior and we'll import I know there's a lot we got to do SOI all right you know I need to import flame behaviors get over yourself and we need to import flame components and we need to import the zombie game okay so that should be redundant what zombie game doesn't import oh right that's not the top level Barrel file okay all right moving Behavior here we go so move along path what does this method do path to player wolfen what's your intuition what are the other I think I'm just currently living in a horrible no man's land in between flame behaviors and Flame steering behaviors and uh things are going to be really stinky until I get out of said No Man's Land apply movement apply Lurch and move along path are the methods so move along path takes a path to player and that is actually again well was that mod ified so this is where I was this is the Crux of what I didn't like about my old system Right Move Along path takes a line and I called it path to player but really because this is what was going to actually move the thing it was if we look at where it was called which has now been copied into this chasing Behavior class it actually was passed path to take which was after the vring had been applied so maybe this needs like a late Vector two that is the path to take and the job of the chasing Behavior class is just to set this the point of this class is to set this for the moving Behavior I will probably grow to I'll probably outgrow this I will come to not like this thing but that would be path to take is called here apply Veer to [Music] path what's that what were you what are you mad about line you take a path path to player what are you mad about the value type line can't be assigned varable oh okay fine line okay and then move along path is not going to be called here uh and then in wandering what did you do so you had a wander path so this could also maybe be like the path to take late line path to take and these could even be like a typed mix mix in what if I had Mixon path finding behavior on behavior and you just have late line path to take and then y'all [Music] use that mix in and you that's not where I meant to put it actually I also don't know if this can work I didn't read that error this might be a dead end okay what what are you upset about okay yeah we just need to not double implement this H oh no still a problem can't Implement both Behavior zombie and behavior entity mix in oh yeah that's fine zombie okay now we're good so this path to take is what we're setting and so now down in random wandering Behavior Uh path to take we also remove we'll just use it from the Mixon hit the wrong key here we go uh so with that and path finding Behavior so wander then we're not going to call apply Movement we have just setting it's not wander path anymore either it's now path to take Vector two oh this one went in the other direction really apply movement took a oh right it takes uh yeah yeah so you move along a vector 2 because you already know your own origin the path to take I guess that should like also be a vector too it shouldn't be a line but that's going to be a really nasty refactor it needs to be done but not today what is the easiest way to bridge this Gap um where did a does apply movement only get called from Yes it only got called from Move Along path and move along [Music] path gets called from Chase wow this code is the worst code I've ever written in my entire life what oh it also got called from Wander so everything went to apply movement both chasing and wandering went to apply movement is that right apply movement was called in Move Along path this is the worst code in the universe Move Along path so chasing definitely went in that direction via Move Along path and wandering just went straight to apply movement interesting so what did move along or what did um whoops what PA path to player Vector 2 normalized that oh right lines can just return their vector [Music] okay so apply movement could begin to take a line and we'd pass in we just pass in the path to player here so this is the line to take and then final movement equals uh line to take. Vector to oh no this isn't going to work because this normalized part isn't always what we want we don't want every game character moving the same amount that is why apply movement took a vector two I need to stick with that oh I think I have an idea I think what I need to have happen is my pathfinding thing doesn't store a line it stores a vector two that is the movement to make let's call it that and now movement to make here so this would be final and then movement to make equals path to take. Vector 2 because we don't normalize in this one but we do normalize here so this was Final path to take and then movement to make now I'm starting to sound like a who sang that song every path you take every movement you make um apply movement there we go so that was this one was normalized there's no chance this code is going to run before the end of the stream no chance in the universe uh path to take. vector 2. normalized what is your problem Oh path to take was already a vector two Wonder path is a vector two okay then that means you would just be wander path oops okay this code is not going to run today we are not going to see this happen again and it's going to be really easy to continue this effort uh the next time I stream in January like what did I do last time uh all right so wander sets movement to make that's the goal that it had oh and then there was this apply Lurch oh goodness gracious did that get called anywhere else no all right lurching I feel like this happened all the time yeah that's why it was called in Move Along path everything was supposed to Lurch and the double oh the Del the delta time was just kind of truncated or not all right this is kind of what I'm thinking I think I want to have an actual design document for how this class should behave and it's going to basically show like apply movement it doesn't make sense to have this Vector 2 and a Delta time passed in because the Delta time is scaled up and down for like lurching purposes so the zombies kind of take a step forward and then they sit around for a second while they collect themselves and then they quickly take a step forward again and that could just be collapsed into the length of the vector so these two things as different parameters don't make any sense and what I kind of now am thinking is I think I still maybe we're basically right there movement to make this should just include any like speed Buffs or debuffs that are going on for the zombie right when it's its slow phase of the lurching cycle we could say that it's kind of got a movement debuff and that should just be factored into this variable as opposed [Music] to uh as opposed to being a parameter here like what is this even yeah this doesn't make any sense at all I don't like that so apply Lurch happened in Move Along path and move along path happens only in chasing so when when they were wandering I guess they don't Lurch that's a little bit of a surprise but I think that means I can bring the lurching part into Chase so let's get let's grab a Ply Lurch and I'm going to put this in the oh and this was setting the movement State yeah that's not g to work great holy smokes that's gonna break everything so much rendering and state logic all completely interspersed I briefly had a tiny bit of hope that this was going to run again before the end of the stream and now I've lost that hope completely so um yeah movement State like that's terrible I actually don't I can't even copy this in here let's actually just read what it does and figure out what to make of it so if the zombie is standing still then we say if if the date so if the time since the Lurch start so basically this is if the Lurch has totally um if the Lurch has totally elapsed then we move into the stepping state so that make sense this would be next we remove idle we start the walking animation and then we reset our timer that was if the zombie was standing okay and then we were return zero this could have really used a comment huh I guess the idea here is oh the speed because the zombie standing so the speed is zero okay no that actually makes sense otherwise so this is if the zombie is uh stepping down here we'd say if again the Lurch duration has passed then we remove walking and we start standing still and we set our state to standing yeah this is going to need to be another Behavior well kind of not I mean I guess the the switching obviously we don't want to be like doing this animation toggling but basically what this is saying is that even within chasing there's a substate of standing or stepping so chasing is again yeah and I guess it makes sense that this would only be in the in the chasing mode also wandering mode is for like offscreen zombies so we don't really care what they're doing they don't need the extra logic so I guess apply Lurch can go into Chase we'll need to then bring back out any concept of these uh animation components but this movement state is going to be a thing on the chasing Behavior class and the movement State enum itself will move into the file and what else did we have down here in uh apply Lurch okay so Lurch started at so let's grab all of those fields here we go lurching lurching lurching looking good so that goes all the way down to here so those compon those fields will so we have veering and lurching I'd like to separate this out more I guess this could just be uh parent. remove and parent oh uh let's make this a whole method so let's let's have this be um parent do use walking animation and down here this could be parent. use standing animation I think this is probably not where this logic belongs but that's going to be a headache for another day void use standing animation great and then use walking animation use walking animation and this would be add and this would be [Music] remove okay so now we can get rid of those lines okay Lurch duration get standing Lurch duration that's a method that we pull in there was another one Lurch step duration let's just grab both of them it's clear we need them both undefine named Lurch started at oh this was in onload okay so that is behavior that I'll move into on load of the chase thing override unload void super. onload and let's get both these okay set ver not assigned oh where are you you're in onload okay set verer will just get called here I guess and apply Lurch at last now we get to move along path is this method even still a [Music] thing no it's not called anywhere now I commented this out and I'm not going to lie I don't remember if I thought it needed to be moved oh yeah I was making the moving Behavior I probably commented it out because I was going to put it there let's oh wait wait wait what did so I just brought in so apply ve that one we're already using I brought in apply Lurch and I'm just simply not calling it so that's fine but I need to call it I think a Move Along path is going to be a uh I want to multiply this by like a yeah so apply Lurch on the speed on parent. speeed that's what this does we either oh we return speed why does apply Lurch need anything yeah this is actually just stale I don't know why we had that um uh fine we'll pass it in no no no no we would return parent. spee that's what it is yeah yeah yeah because everything is typed because that's the whole point of this Library so now in where I was just calling apply Lurch we don't do that well apply Lurch should really probably take a vector yep that's what it'll do that way would be nice that would be a lot cleaner so apply Lurch will take a vector and here we just return uh Vector 2.0 and then here we return the movement Vector okay stop coding play pubg uh I do like pubg gosh that's a fun game uh if we don't talk again for a bit happy holidays Craig you too Randall another Festival festiv us for the rest of us that's right uh hope is feudal it's feeling pretty feudal right now ain't no doubt there um so apply Lurch right so you just take the movement now see this is a lot better but apply movement's not even a thing where am I move along path this method I think we've I think I've ruled out the existence of this method I'm not going to continue editing that apply movement you should not take a DT anymore there is no DT you just get some movement and now I don't think I'm ever using the DT anymore so that could be bad uh get unwalkable Collision this doesn't even look like it's being called so we're not going to worry about that actually there are no compile errors I am 99.999999999% certain that I have incorrectly moved code into places and I was like I need to move this there and call it and then like didn't call it or called it in the wrong way or you know probably 15 of those errors but we're going to run the game because there is there are no errors now yeah um right yeah I'm not doing that yet well I I don't know if I'm doing that yet I don't I don't remember in Chase no in the chase method so you're here we get the DT and yeah never use it so that's terrible uh so the path to player let's see what happens here so it just sits in place but it's I kind of I thought it would be broken and hard to predict ways I didn't predict that so the the problem could be literally anything and I'm just going to call it for now um game is running yeah ship it if I was uh Electronic Arts then I definitely would and the the bug fixes would be [Music] DLC uh are you adding the behaviors to the zombie oh am I so I'm adding the goal controlling Behavior and the goal controlling Behavior does call the methods that add the behavior so we are yes great question though um yeah so your behavior ends up being nothing or you're end up we end up getting no movement I wonder if we can just spend a few more minutes on this like what is your movement to make are you applying movement or are we not oh yeah I'm not applying any movement because Move Along path got commented out and the other method was called apply movement can you can you restart the game please whoa it shot right off the screen rocket zombies in Flight all right so they weren't supposed to move at all and then it went Bonkers and it moved really fast and then it what moved really fast in the other direction uh yeah but where so movement to make times I guess let's just multiply by the delta T I don't know I think we had some assertion error as well so that'll probably just come right back yep all right this is good for now basic the same error randomly applying the Delta time on an a line of code that received no totally insufficient analysis shocker that didn't work uh then there's also a problem in is it here no where's my there remove idle component so I guess that didn't exist H all right tons of stuff stuff to fix Zip Zap [Laughter] Zoom H folks this has been uh a pretty fun dive into flame behaviors I honestly think I could have had more success if I had just started from scratch with flame behaviors in hindsight if I could whisper one thing in two hours ago me's ear it would be make a zombie2 file and use flame behaviors uh in there maybe it still would have been terrible because I still would have been using zombie one as source as a reference code but there's obviously more to do to pull this stuff apart this code has been very very very bad and soon it will be less bad and I look forward to thinking about that more but that will be a 2024 problem until then uh everyone please stay safe have great holidays whatever to whatever extent the upcoming season is a holiday season for you uh if not then you know don't feel pressure because you know a lot of holidays are kind of overrated anyway uh but everyone have a great New Year's and I will see you all in 2024
Info
Channel: Flutter
Views: 16,920
Rating: undefined out of 5
Keywords:
Id: 6dAJmGEQauQ
Channel Id: undefined
Length: 124min 17sec (7457 seconds)
Published: Thu Dec 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.