 All right, very nice to meet you. I am Martin, also known as Bad Normals. I mean in some people I can say Bad Normals, also known as Martin, which I think is more appropriate here, since you know Bad Normals more than my actual name right here. So we'll be making the Flappy Bird game with simulation nodes, which means exactly that. We'll be making a full playable game with your mouse, which looks something like that, so that you can jump around and depending on your skills sooner or later you will lose. So let's do it for example right here like that. And that's the game. How is it useful? As per say, not at all. But if you want to get into physics simulations or just the general mindset of simulation nodes in general, I think it is a really nice introduction. So before we start, there is something I would like to talk about and that something is myself. A bit about me, just a tiny bit. Which one of you or who actually knows who I am or has heard about Bad Normals in general? Oh, that's heartwarming. So where I keep my little story going, I'm going to show some of the things I've done, some of my work in the background and in a better quality as well. So it actually all started in a bathroom. I had this idea of you know, maybe we should make blender tutorials, right? Because why not? And I was at the time in a music academy and I was, you know, not very happy with the thing in general. So I thought like, okay, let's make a blender tutorial. I made a tutorial about Minecraft, even though I hadn't played this before. And it did like maybe 30 views. And then I made one of Among Us and this got like maybe 20 views. And I remember I was in a cafe with a friend and he told me like, oh, you have like seven subscribers. And I was like, yeah, I know, it's crazy, right? Seven subscribers. And the next video was about geometry notes, which did a bit better. It received 10,000 views in like two weeks or so. And you know, for a moment, I felt like a star. And this actually got me into the procedural things overall, because before that, I didn't have any experience with coding, any experience with notes or anything. I just were a broke music student. And I started learning geometry notes every day. I put in a lot of hours just, you know, getting better and better and better. And I started making some intros for my videos, which are the ones that this video is made of, and got, you know, better and better with every video. And up until now, where I'm actually giving a talk about simulation notes. So the channel is one thing that I'm doing. And the other thing is another company actually through those videos, I met another person and we are doing procedural materials. But this time, you know, without this whole note hassle, we are actually making a new way to make them with a much easier setup. And we're also looking for procedural artists. So there are some contact links in the description afterwards. Right. That's what I do. And with that said, I think it's safe to start. Although I finished this quite a lot earlier. I'm just going to show you like this frame here a lot. This one looks so cool. Just looking at this final animation, then we can go. Yeah, you know, it zooms like in I used Nuke for this for the first time. It was kind of crazy. Okay, that's, that's what I do. So let's start now. If thanks. Thank you. If you want to go along, which I see some of you have computers, which is very nice. Then you can go here to this link and you can download some assets. It actually has the end result and the initial file of this bird thing. The initial file and thing is the one here and the initial file. I'm gonna show you right now. And we're gonna start start from here. Okay, so if you want to create the flappy bird game, the first thing that we need is the bird, which we luckily have here. So you can see you have here two assets. And one of them is the birds. The other one is the pipe. Now, the first thing if you want to, you know, make this game, you probably think, Okay, what birds? What does it have to do? It has to be in the air and it has to like, jump like that. Or actually, it's done jumps in a place. And the pipes move. So the first thing we should do is actually implement gravity so that the bird actually falls down in a more realistic way than just moving gradually. Let's add a new geometry notes window here. And let's add this random object like a cube that we can add some notes on. And I'm gonna call this note set up the game itself. And also, I'm going to call the object itself game, because it's rather important to name your things correctly. For example, if you come back from lunch, you don't understand what you've been doing. So it's important to at least try to make something. Okay, we could just drag in the flappy bird and start working with that one. But you know, the bird asset itself has quite a lot of geometry, or like four points. But it's easier to actually apply gravity on a single object. So like a just one point, for example. So let's delete this flappy bird. And let's add a new thing called a point. And if we output this, and hide the assets because we don't actually need to see them. Then you see we have one point in the corner, right here. I'm gonna try to make it comfortable here. Now, if you press play, the point doesn't fall. And that's because we haven't told the point to do so. So what gravity or free fall actually means is that we, you're not just for moving down a little bit on the y axis. But it has to happen on every frame. And if something has to happen on every frame, this means simulation. And let's, let's remove this one, let's connect those so that we make a little point. And then we start to repeat something on every frame. And we output this as our geometry. That is how simulations work. Simon gave a really nice presentation about this yesterday. I hope you watched this. I watched it was very nice. And, well, let's add the set position note back. Let's put this here. And let's say our gravity is I don't know minus 0.0, 0.02, for example. And if you play this, it starts to move down every frame. This is a horrible way to do gravity. It is very incorrect. And it doesn't really look like gravity doesn't look like free fall. So I think you have heard about a certain number called minus I don't have a gravity stop at 9, 8, 9 meters per second squared. What does this mean? This means that the gravitational acceleration is that. And at the first time moment, zero, the speed is zero. The next second, it will be 9.81. And the next after that, it will be like 20. So it keeps increasing in speed unless you have air resistance, which you probably know. Actually, in physics tasks, you never have a resistance, right? You just ignore this all the time. And that's what we will do as well. Okay, so let's store an attribute, which is our gravity. It is a vector attribute since we are actually interested in a certain direction, which in our case is down minus 9.81. It's not 10. Like that. And now we can do so that let's take this gravity here. Select attribute. And do you like that? No, we don't do because the gravity actually gets turned into or in case the gravitational force gets turned into the velocity. The velocity is the thing that moves the object. Let's do it so that we take a stored name attribute, and we store a new attribute called V, which is the velocity. It is a vector attribute since our objects moving different directions, not just in one. And the velocity attribute will be composed of the velocity itself from the last frame. And then we apply some new forces to it. So for example, if I have my phone here and they just like punch this force gets applied, phone moves, not too far, hopefully. And that's how it works. So let's take vector math notes, put it here and we add gravity to the velocity. And then we use the velocity to move the object. Where is our point? We don't, we don't see this anymore because the force is very extreme. Currently, I think the point is, yeah, here it is. It's ways to way too strong. And why is it so? That's because of one great big reason. And the reason is, you know, when I'm moving, I'm not moving, I don't know, seven meters per frame, I'm moving seven meters per second. But currently we are doing everything per frame. So every frame that we play down here, we reiterate the same setup. And this is way too fast, because we have currently, let's make 60 frames per second. So we should actually do this only 160th at a time. For that, we need the delta time, which is, in our case, one divided by 60. I have used this one here, but I've also gotten some problems. So I'm just going to store a new attribute called delta time, which is currently one over 60, like that. I'm going to put this here. And now we can just scale the gravity that we add with this time stone. This should give us a very acceptable result. So you see already, it is quite a bit slower, but the speed is itself as well, you know, per second, not per frame. So let's scale the speed as well. Let's duplicate the delta T and we should have a really nice free falling point, which can serve as a word. So the first step is done. Let's group this thing. Let's call this gravity to velocity, velocity. And let's group the other thing as well, because otherwise we will have a huge mess going on. Let's group this one and let it be velocity to position. This is the basics of actually, I think most of physics simulations, where you have some forces, you apply them, you create like a velocity vector and you move objects with this velocity vector. This is how it works. This is ready. Now let's instance a bird on this little point here. Let's take an instance on point, like here, dragging the flappy bird asset and let's instances on this thing here. And if you now go to the material preview, we see a bird that's falling down just like in the game. This camera here acts as our game window. So what I will do is that I will move the bird in a more suitable location. So the point here should be maybe somewhere I would say around here. Let's make it also larger so that it's nice and understandable, something like that. Okay, the bird is moving. How do we make it jump? This might sound a bit hard, but it actually is pretty easy. So I'm going to make it so that I'm going to add here a store name attribute that is storing the same velocity attributes. So here we create this velocity attribute. Here we do something with it. And here we apply this to position. But what we will do is this one, you know, you see stores the velocity into zero. So if I play this now, nothing happens. Disable starts to fall like that. But what if I would what if I would add instead here, like a new acceleration? If I play this, I can enable this and the bird starts to jump because it receives some extra velocity at a certain moment. However, there is a massive problem. The problem is the bird has a bit too much energy. So if I play this, you know, I can keep this in and it will continue to go on forever, which is not the case with the real game. So in the real game, you tap on the screen and doesn't matter how much you hold your finger here, it will actually just, you know, get one impulse and pull back. It's not like you keep your finger there. It's gonna like go on like a rocket. It doesn't do like that. So let's create an impulse. It is a bit of a thing to do. Since you know, you cannot actually get click information in Blender, you cannot get the click information. So let's build our own little game controller. For that, I'm going to move the cursor to the world origin, add a little empty here like a cube. Make it smaller. And let's do it so you see the center of the empty is this yellow little dot here. So if this yellow dot moves over the red line here, which means it gets positive on the y axis, then we register a click. But not like when I, you know, move it over and keep it there. It will not keep giving me the click. It will just give it once when I've moved over and then reset black to, you know, false or reset back to false. Okay. This sounds like a pretty complicated problem to just start with like on the go. So the first thing what we need to understand is, how do we understand if this empty is higher on this or over the x line? For that, we need to get the position of the empty. So I'm going to pin this game here. And I'm going to drag in the empty. And honestly, the problem with this empty is we cannot store any data on this empty because it's an empty object. And but we can only store data on, you know, points, edges, faces, face corners, splines, instances, and empty is not one of them. So what we will do is that we have one point for the bird acts as our bird. And we have another one, which is our controller CTR, CTRL, like that. And we will just join them together and add them into our simulation, both like that. And now we have the bird and this controller, both going in. And if we will see where is the controller, we don't see this because it's in the same location with the bird. So I'm going to reset this to zero. And now we have two birds, not optimal. We need actually only one. And in the end here, we see the instance on all the points currently, but we should be able to select only one. And for that, we need to add a little separation attribute. For example, on the birds, you can create an attribute called bird, which is a Boolean attribute, you know, just true or false. I mean, you don't have any mixed feelings. It either is a bird or not. I mean, there is no question about that. So a tick box, this is a bird. This is a controller. Or nice and clear. And now we can go in the end, add a little name that tribute here, where we have our bird, put this here. And now we only have one left. So the controller has now one point. And this point that we currently don't see, because we only instanced on the birds, I'm going to add the joint geometries that we kind of have, like both of them visible. The point here should move with the controller. So it acts as like a little memory stick of the controller. So controller moves somewhere, the point moves with it and records some data about this. And we can use this in our game. So how do we move the controller into the same location? If you play, you see the both fall down, which means that currently everything we do is both for the birds and also for the controller. But they are clearly different objects. We don't want to do this. So I'm going to move the bird things up here. And down here, I'm going to add a little, like a separation and join them together like that. Now, this is not different. But I'm going to add a separation, a separate geometry. So up here is my bird. And down here is my controller. And for clarity, I'm also going to name this bird plus controller. And of course, it doesn't do this right now. I have to separate based on the bird. So what the setup now does is that it finds all points that have the attribute bird true, which in our case is only one point and separates this up here. So the bird starts to fall down. But the controller doesn't. Since the controller is, you know, we do nothing with it. What we wanted to do is to move the point where the controller is because when I play this, and I select the empty here, you know, it doesn't move with my empty. Let's take a set position. Since we want to change the position of this point, take the empty and let's use the location of the empty as the location of our point. Now the point moves with us. For a controller, it would be more convenient to have this only move up and down on the y axis. So we can add a little con the constraint limit location. So we limit everything and do like maybe minus 0.25 and 0.25 on the x axis. So now, however, I move it will only now move like a controller or like a little gamepad switch. And this is a pretty playable device, I would say. Okay, let's let's group this thing. And let's call this move CTRL to empty. This one is done. But how do you register the click? Then we have to first understand if the controller is above or below this X line here. For that, we need to understand the position. So if we take the position of all of those points currently, and we now separate this into the X, Y and Z components, we are interested in knowing how like high is it on the Y axis. And for that, we can use a compare nodes. So I'm going to take the compare node and compare if on the Y axis, we are, you know, higher than zero or not. If I now move this, it is higher. It is lower. It's higher lower. But it's, you know, kind of doesn't, you know, turn itself off. It still keeps the click as you see right now. Let's play the animation. Let's see how it works. Yeah. I mean, it turns white. And we could use this as the, as the switch here, but it doesn't, you know, kind of work because you see it keeps itself being white all over and the bird is still going to be like a rocket. So we don't want this. And let's think about how we can solve this. So to do this, I'm first going to store this thing here that we made, whether or not it is above the Y axis. I'm going to store this as a natural chord current because it is the current state of our switch. It's a Boolean attribute like that. Not going to group those yet because we have some more things to do. Move them here. And in the end I'm going to take the current attribute and preview this. And now I'm just going to, you know, make my emission play into like that and go to a certain, you know, it was a bit too fast. I'm going to do like that slowly. And now let's zoom in here and see. So when this is below the red line here, it will always be black. I mean it will always be false. But when I start to move up and up and up, now it gives me the impulse. And on the next frame I want this to turn off, but it doesn't. So we need to introduce a logic for that to work. And my idea is so that we store the current position as we just do here. And we also store the previous frame position or the value here. So currently on the previous frame it was black. Now on the previous frame it was still black. And on the next frame it was white. So if two consecutive frames are true, this means turn yourself off. We don't want you anymore. And let's create this logic. Let's see how this works. So how do we get the previous state of this switch for that? Let's use another store name attribute that we can actually copy from here. And before we write this current attribute, let's take the current attribute and store it store itself. And let's call it instead previous. So how does this work? It might be a bit counterintuitive, but it works so that on the very first frame zero we write an attribute into previous. But we don't have this attribute no more. So this will be like empty or something. Then we will write a new attribute called current. And on the next frame again we will store this current attribute as previous. And we will be doing that so that we always have access to the last frame. And this is what gives us the ability to make the switch. So we have this and previous and current. And now we need a third attribute where we combine them together using our logic. And this will give us the impulse. Just one little click when we move about this. I'm going to add a new attribute which I'm going to call impulse. And for that we will use the current state and also the previous one. But how? That's the question, right? Do you be honest? I figured this out a few months ago but then when I started practicing before the conference I had forgotten that. So I was like oh my god how did I do that? And now I obviously remember. So let's go over this logic once more. We have this I'm going to open up a spreadsheet. This gives us even more context. Your nodes. And here we have two points. With all of our attributes. We have previous attribute, impulse attribute. Is this a bird? Is this a plane? Recontroller. And we can understand based on that. And I'm going to play this again. Do you like that? So we have a little case here. And let's see. Okay. So here two consecutive frames are true. Okay. I'm going to add a Boolean math node which helps me do some logic operations. Actually the whole CPU of computers is built with those expressions. And those are like really clever people who come up with such things. And we will compare our decorrent and the previous frame both true. So you can see in the spreadsheet right here. So the previous is true and the current is also true. If you go one frame back you see the previous is not true. Okay. And if they are both true we should turn itself off. So I mean if they are both true which they are right now. Then let's just invert this. And let's say turn yourself off. Like that. So this is something that we need. And now I'm going to use a switch node. Because our controller has two states. It is either above the X or below. Now if this is below then we actually you know we don't care. I mean it can just be the negative value here. We don't do anything too special with it. So I'm going to make this a Boolean switch. And if the current attribute is false I'm just going to use the current attribute. If the current attribute is true which means it's over I'm just going to use our newly created logic system. I'm going to put this here. Like that. And now let's switch this attribute here for the impulse. Let's see if this works or I'm just talking nonsense. It does work. So I'm not talking nonsense obviously. Okay we have the switch here. And I'm going to order impulse. I'm going to group all of that here. It gets a little bit messy. And call this thing impulse logic. This is the impulse logic. And now we just should somehow get this impulse to our bird. Since currently we are writing this on the controller and the bird doesn't know anything about this. It's like in its own bubble here. So really doesn't know what we do with the controller. If you preview this attribute you know if you play this you see the controller is flashing but the bird isn't. So we should somehow get this attribute onto the bird and make this enable this node. Obviously we cannot enable actually a node. It is more of a UI thing. So let's instead use a switch and the switch does so that when the jump is true it uses like a new velocity that makes it go like that. And when the jump is not true it will use the previous velocity. You know just keep doing its own stuff. We just need to get the impulse somehow here. We're going to do it like that because the geometry of the bird doesn't contain this attribute. And for that we luckily have a node called sample index which which can sample based on the index of the point. It gets a matrix from it. So the index is like the address of a geometric element. For example if you have only one element the index is usually zero and second one is one and two and so on. Now since our controller geometry only has one element it's pretty safe to say the index is zero because there is only one element it won't be probably 70 or something like that. And from that geometry we will be getting the impulse attributes and we will be using this as the switch for our bird. So you see right now it works because every time we get an impulse it really works. It takes it into account. Let's group this control g and call this maybe jump switch would be pretty appropriate jump switch. And this is I mean pretty much the logic of the bird itself. Now the only thing that we need to make this game more like a flappy bird. I'm also going to play this or make visual. The only thing that we need is to be sure that we actually have some pipes that we can collide with. Okay collisions you know dying birds sounds fun. Let's do this. For that we need the pipe asset. The pipe asset this is right here in our scene and we need to spawn this into our scene. So how do we do this? We basically do so that every frame we take the pipe asset and we add this to our geometry. Then we move this a little bit and then we add a new one and remove them all a little bit so that we just you know keep flowing some pipes into our scene. I'm gonna hide this. Let's do this. But the problem is where do we add this? We could be tempted to just add something here but I mean this is actually the controller lane here we do some controller stuff here we don't want to mess with that one. We actually want to add a new separation here and separate the controller into its own safe you know space here and the rest that is coming from here will be our pipes and we will pipe the pipes in the end. No does this work? Yeah we'll pipe the pipes in the end. So here I'm going to add a joint geometry and on every frame I'm going to take this pipe at the object and I'm going to put this here. On the first frame we have this here. Now if I play this obviously we don't see anything because they will all add it to the same location. So instead I'm going to take a set position node and use a finely tuned value that I've been practicing seven times of minus 0.02 meters. This does it so that when I now play this we start to have like a lot of pipes added into our scene and all of them move which is kind of good but not very practical. So obviously we have a lot of them. We would actually much rather prefer to have you know let's say every 40 frames you want to add one pipe and then another 40 frames also. For that first we need to understand how we can even turn this flow off and for that we can use a switch. So for example if I turn this into true it will use nothing and if you add nothing to your scene it won't have any pipes and we will you know you control the switch dynamically so we'll use the scene time node and use a math operation called modulo which means the remainder of a division and in human language it means so that if you have like frames and you do mod five it will be like zero one two three four zero one two three four and so on and keep in mind that there was a zero there and we also have this thing piped into false so every time there will be a zero we will use this pipe. Let's put it to 40 and now every 40 frames we will have one pipe flowing into our scene. We don't get anything on the first frame which is annoying if you want to change positions or anything and understand what we actually do so I'm going to subtract one here and seems to be working yeah kind of shifts incoming frames a little bit so it makes more sense. So now we had the pipes flowing in but not from the correct location let's go to the camera view and move them where we want them to move now it's very important where you're going to move them because if you move them right here this will be done on every frame but we will just change the position of the new ones so I'm going to move the new pipes added here actually I think would be better to use transform nodes for that make it a little bit larger if this looks nice we have lost the material though so in the end I'm going to add a set material and get this wall material we're back like that and now we have some pipes flowing in but you know in flappy brood actually have you know we have ones in the bottom the ones in the top and they are you know can't do that with my fingers but you know random like that so let's make let's do so that these are like the ones below and we also have ones on the top so we're going to join the geometry these are below and these ones are top go to the first frame I'm going to move those ones up rotate them 180 degrees and yeah this is a bit too difficult I don't know kind of the same like that so now we have pipes up and down flowing in they are very very uniform though I mean they are just a straight line so each frame when we add something we should move it in a you know random up or down or whatever we want to do with them for that let's use a set position node let's add this here currently we're only doing from the pipes up here and let's add a random value because we want to move them randomly so I'm going to take a vector random value put this into the offset does like that not very good so what do we do the problem is in the id here so currently it has this node works it's going to take an id and based on that id it's going to generate a random value and since this one has like I think four points this asset then well the id is going to be different so every point is going to have a different value but we're just plugging like a random number here like zero and now the random value will be the same for all the points let's do like 0.5 and maybe actually this is this is a bit too much so I'm going to make it vary on the y axis by 0.25 but if you play it won't still be different and that's because the seed here is the same for all the frames so let's take the scene time node and plug the frame into the seed and now you have some different types coming into your scene in a pretty I would say nice way let's copy that let's do the same thing for the for the for the pipes down here offset is it working I would say but the no it doesn't seem to work very well though oh yeah of course does work yeah but the seed is also I mean the same for both of them so the form like this symmetrical thing now they're different okay the pipes are flowing into our scene everything is nice now we need the collision system so I'm going to group all of that and call this spawnpipes spawnpipes move it here like that how do we create the collision what is even a collision actually I mean this sounds like it just kind of a trendy word that everybody talks about in computer graphics but collision is actually when you are you know you know things touch right but we cannot do it kind of like that in computers because we have discrete frames so we might have you know a wall and then we have like an object and this one frame is here the other frame is here and the next frame is maybe here I mean obviously we had a collision but where I mean there are complex and more complex ways to calculate the exact point but we'll just do so that when it is in a certain threshold like here or here kind of already collided so for that we have a node called proximity geometry proximity and we can find the proximity of the bird to the pipes so if we take the viewer node here and we start to play why can't I choose this okay so you see it turns it's white currently but it becomes like dark in some regions because it has collided with those with those pipes I'm going to use a compare node to make it a boolean value either a collision or not so if the distance is like less than 0.05 I think it's the collision it can be any value but you you can tune this yourself um so this is the collision and I'm well let's do so that something happens when the bird collides what usually happens when a bird collides with something like that right so let's do so that we use instead of this jump switch we kind of create another switch which is a store name attribute vector we store the velocity again and when the collision happens vector if it doesn't happen we're going to use the same velocity as always so velocity right here if it does happen when this is true we're going to use something you know like minus 10 so it kind of like goes down like that and let's put this here and let's put this here sounds like here nice idea right so let's play and let's see what happens yeah it's easier to develop a game than to play this so it moves down but you see it actually can come up again yeah you see that that's not very that's not very good you know so we need to some way for the bird to actually remember it has crashed i mean it's not the case with every bird that they remember that they have crashed but this one actually should so somehow we have to keep this in memory and for that we're going to use a solution like that we're going to create an attribute called boolean attribute called lost so the bird has lost the game and into this attribute we're going to store that one and we are going to use this attribute called lost as the switch now this is the exact same thing as we did before no differences but what we are going to do is that we are going to also take the lost attribute from the last frame like that and you know let's say we haven't lost yet so can you even actually hear me if i'm talking here yeah you can still hear okay right so let's say we haven't lost yet so this means the value is false false false and we keep adding it to itself but since this is you know zero it actually won't change anything but once we lose and we add this one kind of you know we pour something into this this cup you know there is water inside we cannot get this out anymore so if we have lost even only once this will be in this attribute and this means we will keep this in mind forever that we have lost okay this is the last attribute doing like that gonna call this lost and let's see if this works now a bit better okay we move we move we move and it turns down and we cannot move up anymore because the bird knows it has to go down it remembers the loss let's call this one lost velocity lost we whatever and this is exactly how this works um now one thing to tune about this is the jump switch here because currently it's a bit it's a bit too aggressive i feel so i'm gonna put this to three and now i can play this in a more in a bit of a better way and i mean kind of it is like flappy bird you know but you feel something is missing here so when we lose i mean the pipes still keep flowing and the bird is like doing like that it's not actually you know kind of smoothly flowing so let's deal with the pipes first so the pipes should stop when the bird also falls down and since the lost attribute is on our bird and our pipes don't have this we have to use a sample index so from that bird we're going to sample the lost attribute named attribute called lost which is a boolean attribute we're going to sample this our bird only contains one point so from index is zero and we will use that as a switch so currently every pipe moves at this speed but if the loss happens they will stop and if it doesn't happen it will use the same speed so let's see now if a play do i get some yeah exactly like that they stop also this is all nice and good but the bird is still very stiff i'm going to group this one and since i have only i believe five minutes i'm not gonna name this let you think what the name could be so the instancing happens here and we should somehow make the bird you know when it goes down the bird should kind of like rotate a biter a little bit more like that and when it goes up it should be more like that luckily we have this information already and this is our velocity attribute but since the velocity of the bird is you know exactly pointing where the bird is looking at and we can solve this pretty easily by aligning the bird the vectors of the bird something else so the bird asset itself looks like that and we want to align the x-axis of the bird so that it looks up or down i'm gonna go back here and we will align the x to the velocity and put this as the rotation hide the assets how does the bird look all right let's see let's see what happens oh so you see it is like a super fast reaction speed bird goes up it goes down and oh my god what is the problem oh the controller was in a weird location okay so you see up down up down this is a bit too extreme luckily there is a easy way to solve this so you see currently the velocity vector is either up or down and this is why it does exactly like that but what if the it had also an x component so it was more like that so we can do this we can take a vector math and we can just add something like maybe two and now the bird should move you know in a relatively i would say better way very nice very smooth and we may be tuned on the factor also a little bit as well so this is how it works let me let me think about if there is something else the bird should suffer from um no i don't think so uh okay just a little background and we don't have enough time to make this background you know react to the loss but how i did this is that i basically you know transfer the same attribute to the background and you can use this to mix between different colors so if the loss happens you can turn this red or whatever color also with the same technique you can add like some text like i don't know you you don't know how to play or anything like that and that's that's how this works so i hope this gave you an introduction to how you can do something like that with simulation nodes it was interesting to watch hopefully and that's all for me thank you also we have two minutes actually so if you have any questions about which jam i like or something like that you can ask me what explain ah we want to see me play all right yeah of course that's what we were gonna do you know actually i should do we have some streams with twitch or something okay well it's not the full screen actually okay well you know actually i'm gonna make this more cinematic you know i'm gonna add some passepartout and we can now get to this all right i hope i didn't make this too hard for myself ah all right i was trying to add a score as well um well this is way too easy actually maybe i'm just a pro i'm not sure okay all right