 Let's make a 2D platformer from scratch in Godot 4. I just launched Godot and have my project manager. I've got a whole bunch of projects that I've worked on for videos and my own projects. Yours might be blank. Yours might have other things you've done. Regardless, we're going to go over here, click New Project. And then we're going to name our project 2D Platformer. You can name it whatever you want. If I wasn't making this as a video, I would call it Devil Boy because I think that will be thematic with the sprites that we're going to use. But place it where you want it. You can browse. I know exactly where I'm going to put mine. So, you know, put it wherever you want it. Obviously, don't put it in the screencast folder because you ain't making the screencast, right? Click Create Folder. If you just typed it in, these have to exist for Create Folder to work. But again, you can use browse. Then we're met with our first sort of Godot bit of choice. Our first choice in the game of Godot, which is which renderer to use. You can do Forward Plus. That's advanced 3D graphics. Well, we're making a 2D game. You can do Mobile, which supports desktop and mobile. It's for less advanced 3D graphics. Fast rendering for simple scenes. That's pretty good. Compatibility. Fastest rendering of simple scenes. Supports desktop web and mobile. Least advanced 3D graphics. Well, we're not making a 3D game. So, I think compatibility is great, especially for 2D projects. There might be other reasons not to use it. But from as far as my knowledge is, is I choose compatibility unless I'm making a more advanced 3D game. Click Create and Edit. That will create your project and open it in Godot. You can see the name of your project here. And you're met with this screen. We've got a lot going on. And I think by following and watching, you'll catch on pretty quick. You're first greeted with this 3D view, which is up here. You know, we're not making a 3D game. So, you can just click to 2D. And you lose the Z axis, which is nice. And now we have a Y axis, an X axis, and we're feeling good. What else should I show you? Over here, we've got the scene view. Scenes are different views into your game. The main menu is a scene. Level 1 is a scene. Level 2 is a scene. Settings menu would be a scene. Those are all scenes. And then even, like, objects within your game, like your player, gets created into a scene that we load into other scenes. So, scenes are a very important foundational part of Godot. And don't worry, we'll make our fair share of scenes. Down here is the file system. Godot makes it really easy to view the files in your project. And here I've opened them in my Finder. It would be Explorer if you were on Mac, or on Windows. I'm on Mac. And you can see we're at the path I created. We have project Godot. And then we have an icon that Godot gives us here. Over here is the inspector. We'll get to that soon. And in the middle is our workspace. So, let's start by clicking Add to the scene. And that created our first scene. But we haven't saved it yet. You'll see up here it says Unsafe. Let's start with the main menu. Boring stuff, but I think it'll really illustrate a lot of the important parts of Godot before we get into gameplay. So, I'm going to press Command S. You press Control S if you're on Linux or Windows. And save main menu in our resource file, which is our project directory. And TSCN is the default scene name for Godot scenes. I name things Snakecase. So, lowercase with underscores to connect them. Looks like a snake. Click Save. And then now you'll see here we have main menu TSCN. Open it in File Manager. And we have our scene there. So, we just created a file. You're not often working from outside of Godot except when you're importing things. So, that is what we have there. Now, our main menu scene doesn't have a whole lot going on, but that's okay. Let's click this triangle here, the Play button. It says no main scene has ever been defined. Select one. You can change it later in project settings under the application category. So, this says when you launch our game what scene should be displayed. We want it to be our main menu. So, we just say Select Current. Godot launches. You can see the title of our game here, 2D Platformer. And an empty screen. So, it begins. You can just close that and it ends it. But another nice thing is you can just keep running. And most of the time, unless you change some fundamental things, Godot will go and automatically reload it as we make changes. So, let's see that in action. I'm going to just click back here, but that game is still running. We'll switch to it in a second. I write clicked. And I'm going to do Add Child Node. You can also do the plus sign here. Do the same thing. Also, Command A, Control A does the same thing. And this brings up our node view. We're met with another decision tree in Godot, which is what are nodes and how to add them. So, if scenes are collections of nodes in a tree format, so tree means that you can have multiple children and they can have children and you can group them together in that way. And you'll see there's a whole bunch of them. But here's what I want to tell you. You don't need to know like 70% of them, right? Only 30% are the ones you're going to use. And you're going to use them all the time. So, don't worry. It's okay. We'll go here into Canvas item. That's something that's drawn on the canvas of our game. And we'll expand node 2D. And these are the ones that we really care about. And you'll see these will be things like animated sprites, things that have physics, like our character body. But I jumped the gun a little bit. What we actually want to do is go into Control. And we're going to add a label. A label is a way to display text. So, you just select it and click Create. And you'll see now our main menu has a child node called label. And over here in the Inspector are a bunch of properties about it. Click into text. And you can type something in. I'm going to type in 2D platformer because this is going to be the title of our game. Double click the label here and just rename it the title label. That helps you keep organized and see when you're working with the scene what it's named. And just drag it kind of to the center. There are ways to precisely center something on the screen. But let's not worry about that now. Just know you can add it and drag it. And then let's actually go back to our running game. And you'll see 2D platformers there. But it wasn't centered. So sometimes you might have to rerun your game, but now you'll see it centered. If we drag it, it moved there. You might not have noticed that. Drag it somewhere. Move. So sometimes you got to like when you add new nodes, you got to rerun your scene or your game. But for the most part, you can just move it around and change it and just adjust it till it feels right. That feels pretty good to me. If you change it here, just add an s at the end. It updates it there. Let's look at a couple other things. We could make the labels with the full width of the game. And then we could say horizontally center it. That's one way to center something. It's kind of a funny way to do it. But you can change text alignment. Good to know. What other things are relevant right now? Let's go to theme and click type variation. And Godot comes with a few out of the box. And let's make it a header large. That will make it bigger, which is just nice. It implies this is the title of our game. This is what matters. And yeah, we're getting there slowly but surely. So in the main menu, we're going to make it so that you can start the game. So I've gone. I've selected add a new node. And you can actually type in up here what you're looking for. We're just really helpful when you're trying to find something. And we're going to add a button. And this button is going to be called start button. So rename the node there and change the text to be start. You can see this button here. We'll drag it to the center. Just click and drag it. If I can do it. There we go. And we'll just approximately put it in the center of the screen. Go back to our game. It's not there, right? Sometimes when you add a new node, you have to rerun the game. You can actually hover over it and click it. And you'll see nothing really happens. So we've got our main menu seen. We've got a label node. We've got a button node. Now let's dive into a little bit more complicated topic, which is having parts of our game, nodes of our game receive some sort of action and then cause something in our game to change. And this is where we'll start to introduce coding. So when you have a node selected, you have the inspector, which we've dived into a little bit here and there. You can click this other tab called node, and you're greeted with another sub tab called signals and groups. Don't worry about groups yet. Let's focus on signals. Signals are events. They're an event system in Godot. So when something happens, it allows us to trigger code that runs. And you'll see here button, which is what we added, has four signals associated with being a button, and then it has some other ones associated with other parts of its node that it inherits from. We're not worried about these other ones. What we're really worried about is press. When you see this connect button, if you click it, you'll see this pop up and it says seen does not have any script. So it can't be connected to any code because there's no code. So what we need to do is attach a script to main menu. Click this button up here and it brings up this new dialogue for attaching a script to a node. A script is our code. That's where we're going to type in program. You'll inherit from node 2d because main menu is node 2d. We'll just use the default template. That's fine. And we name it. We'll keep it snake case and click create. This opens up and switches to our script editor up here. You'll see that because it's blue. If we click 2d, we're back to the 2d v port. Click back to script. And we've got a few things going on. We've got a file interface for working with the scripts. We've got main menu.gd, which is the file we created. And that corresponds to this one down here. So you can double click this to open it. You can actually double click. If you double click a tscn, it doesn't switch back. So you just have to know that in advance. But let's focus on this. We've got extends node 2d. This is what the script behavior gets out of the box. So anything that node 2d can do, we can do in our code, which is great. And we've got two functions that already are added. Let's click this button and expand it, make it better. Because when I'm coding, it's nice to just have some space and be able to focus on the code. And we see two functions that start with underscores. Functions are bits of code that you can call over and over again to have it run multiple times. And gdow looks for a ready function that's prefixed with an underscore and a process function that's prefixed with an underscore. Ready is called once when the node enters the scene tree for the first time. It's a helpful comment. And pass just says, don't do anything. Process is called every frame. So your game is running in a loop. It's running over and over and over again. And it calls this function every single time. And it passes in the elapsed time since the previous frame, which can be used to make movement and other things. Frame rate independent, which don't worry about that if you don't know what that means. It's okay. We're going to write our first bit of code here. We're going to delete this line. And with the scripting language that gdow comes with is called gd script. And it's its own programming language. It's a lot like Python. And we're going to type some commands into the ready function to make it do some things. So we're going to type print and not have typos. And then in quotations, these are straight quotes, not curly quotes, when you're programming quotations are straight quotes. And that is where we can insert a message that will get output. So we'll just say main menu ready. Save that, click the play icon to run our game again. And you'll see down here main menu ready was output to the console log. If we changed it, run it again, it changes the message that's output. Okay, let's just double click and copy that. We'll paste it down here and we'll say processing. And we saved it. It automatically picked up our script change. We didn't have to rerun it. We had to rerun it before because ready is only called once, but processes run every function. So now we see its output over 1000 times really noisy because our game's running in this fast loop, right? Like 90 100 times per second. Let's get rid of that, delete it, get rid of the quotes, and then just pass in Delta because Delta is a variable value. We don't have to put it in quotes. And it's actually a floating point number, aka float, and it's usually 0.01 ish. And that's really noisy, not very helpful. So we'll just make that pass again. That's some very basic scripting. We're going to get into more advanced scripting soon enough. But we've got our game, we have our start button, doesn't do anything, but golly, our main menu is sure ready. Let's go back to start button and let's go back to the 2D view and click start button. And you'll see we're back to signals, click press again, click connect, and we're greeted with a nicer pop up this time. It lets us connect it. And you can select a node that has a script that you want to connect it to. We're going to connect the pressed signal to main menu, which is our root node. And we're going to call this function on start button pressed whenever the pressed signal occurs. So you just click connect. It automatically creates a function for us and says pass. Okay, well, let's get rid of pass and make it do something. We can print and we'll say start button pressed. Okay, great. Every time we click the start button, whether we click on it, we can actually press the space bar when it's focused, and it outputs it every single time. That's pretty useful. Let's get into adding our second scene, which we'll call level one. And we'll make it so that when the start button is pressed, we switch to our scene, our first game, our first level in our game. So that was just a quick intro, quick recap to we added a scene, a node 2d scene, we added a label to display some text, we added a button that we wired up with a signal. All of this, while it seems boring, is a really great intro into the concepts we're going to add in our game. So our next step is to add a new scene. You can click this plus button here, add new scene, we're going to make it a 2d scene, a 2d scene. And let's go and rename it level one and click save. It automatically names it nicely. So we just save it. And now we've got level one and we've got our main menu. Let's show you how to run a scene independently from the whole game. So like before we're pressing the play button. And our start button logs there. Great. Now we have level one. We can click this button here, which on my Mac, it's command R, but the shortcut's different on Windows on Linux. You can just play the scene that's currently active in the viewport editor. So now we don't see any menu, we see level one. And we can add a label just for our purposes and we'll call it level one. And we'll just keep that in the upper left corner. I might drag it down just a little bit. Now we see we're in level one. You can close that, right? And just click that. And this is a really great way to test a level that you're building or test a scene that you're working on without having to boot up the whole game, go through the same flow and get there. This will become more apparent as we work on multiple levels. But for now, just know that this is how we're going to launch level one. This is how we launch the whole game. And then if we were to focus back to main menu here and click run current scene, it runs the main menu because it's our current scene. All right. So now we have multiple scenes. Let's go ahead and make it so our start button in the code, you can click this and it brings you to the attached script. Instead of printing start button pressed, let's make it switch to level one. All right. So we'll delete that and we call something called get tree. Remember how I was saying a scene is a tree? Well we want to get the tree. We want to say change scene to file. And as you start typing with gd script, it will help autocomplete. We see change scene to file change scene to packed. Well, let's click change scene to file. You just press enter. You don't click it. Sorry I misspoke. And will it automatically starts to autocomplete our available scenes and we'll change it to level one. So go ahead and save that. All right. Run our game and click start. We're in level one. Pretty cool, right? This again, I know this isn't the game yet, but this is like, you know, you got to learn to crawl before you can walk. And this stuff is going to be foundational. And we'll see at the end of the game how we're going to tie this scene switching in and make it work with doors in our game play. But we're so close. We're so close to game play. But before game play, let's make it so we can go back to our main menu. So in here, we've got our level one scene and it doesn't do a whole lot yet, right? Let's instead of adding a button to go back to the main menu, let's make it so that if you press the escape key, it springs you back to the main menu. This is quite nice, whether you're pausing the game or, you know, for whatever purpose, but for now, we'll just make it go back to main menu with the escape key. And this gets into input maps and listening to player input. What you do is you go to project, project settings. This opens up a whole interface of things. What we want to do is go to input map. This is where we'll configure mapping player input to behaviors in our game. There's nothing here. You see show built in action. You didn't click this and view what Godot has baked in, but it's not recommended to use what Godot has baked in. Instead, we'll define our own. So toggle that off and don't worry about it. You can filter with these, but again, don't worry about that. Focus in on add new action. And we're going to call an action called return to main menu. Click that. I keep them snake case named, just like a lot of things in Godot and GD script. And you'll see it's created and you'll see a dead zone. Don't worry about dead zone. That's for things like triggers and analog sticks where you don't want the action to trigger unless it passes a certain threshold. So just leave it as is. Click this plus button brings up a new interface where it says listening to input. So I just press the J key. It goes, okay, you want to map the J key and it finds it automatically, but I want to make it the escape key. So I press the escape key and you can even scroll through here and see all the options. So if you for some reason don't have the device you want, like we can make it start button, right for a game pad. You can type it in and filter there, but we're going to keep it escape. And then you can add modifiers, which we're not going to do, right? We're just going to say escape design. You click okay. Also, you can see the Godot UI is kind of bugging out. Ignore that. Hopefully that's fixed in the future. Okay, so we made it escape. Well, hey, I really like using a controller. I think it's really important from the get go to support controllers and keyboard and Godot makes that so easy. So let's go back to filter input and press type and start. You can then go and select joypad buttons and Nintendo calls it plus, but everyone else calls it start and just click okay. So now whenever escape is pressed or the start button is pressed, if we check for input from our user, it will come up as return to main menu for this input map. So great. We can click close. Now in level one, let's attach a new script. We'll call it level one.gd create it. Let's, you know, just for funsies, let's just add a print level one loaded or level one ready. Great. Click that minute. Click start. We see level ones ready. Great. Just verify our script's working. You can delete that if you want, but I'll keep it for now and delete the process function. We're not going to use that right now. What we're inside going to do is we're going to hit funk. You can type underscore input and it starts to auto complete and see that input event. That's what we want. That is a callback that Godot will call. We'll call this function in the code rewrite. Whenever an event occurs and an event can be anything like moving your mouse or pressing a controller button or a keyboard button. And as always, we can just print it and see what it is just to see what happens. It's a really, this printing is an illustrative way to just see what's going on. So you see every time I move my mouse, you see down there in my screen says input event key spacebar pressed and then released and you know goes tracking all this input and you can listen to it if you want, but we don't want to listen to any of it, right? We want to see if it was the action we just described. So we'll say event dot is action pressed and then in quotes, we put our action and you see the UI underscore. Those are the ones Godot has built in, but we see return domain menu. You can just press enter. It automatically wraps it in quotes and then we can print that that will say whenever the escape keys pressed or click start. So whenever an action occurs, if it's the action that we're tracking, it outputs true or false. Was it pressed? Well, I just pressed the escape key and it says true and then it was released and it's false. And when I was moving my mouse, it was tracking it too. So what we want to do is add a condition. Conditioning codes are saying when something is true, then we'll do will execute this code. So we'll say if event is action pressed, then you put a colon at the end of this condition, press enter and automatically indents, then we'll say print return to main menu action press. Now if we go back to our game or we'll just go and run our scene. Sometimes I quit the game when I don't have to and that's just like a bad habit. But I just press the escape button and you'll see down there it's being output. I've got a ps4 controller here. See ps4 controller. If I press the start button, it also outputs it down there. Great. Okay. Well, let's reuse some code we already wrote. We'll go back to main menu. We'll copy this here. Bring it back to our level one script. Let's get rid of that print and just paste in our code there. But instead of saying level one, we'll just say main menu. Save that. Now if we press escape key, we're back in our main menu. This switching scenes, while we switch from main menu to level one, and that is sort of, you know, not super fun, you could imagine though that when an event occurs in our game that, oh, we want to switch to level two. So now we can at least get back to our main menu. We can start our game and switch between them. Great. Okay. Now it's time to actually make level one. We don't have any image assets. We don't really have much going for us right now. So let's go ahead and find some assets. I'm going to go to my web browser and I'm at kenny.nl. Kenny is a creator of public domain gaming assets and they make games and tools too. So click into assets and you'll find all sorts of things from platformers to 3d models. What we're going to do is search for one bit and there is a one bit platformer pack. We're going to go ahead and use this to make our game. Because it's public domain, using the Creative Commons Zero license, we can use it in our game. We could even charge commercially for our game. You don't even have to give assets. You don't even have to give credit to Kenny, but I think it's really important to give credit, even if something's in the public domain. So we'll make sure we properly give Kenny credit too. So let's download, download the file and then open it and unzip it. You'll see in here a bunch of files. In particular, you'll see this sample, which is kind of like a 2D platformer level. We'll make something along those lines. You'll see a preview of the images and you'll see some folders, tiles, which are individual tiles that make up what's known as a tile map. A tile map is a collection of sprites in one image. So it's more efficient for the operating system and computers to take it, load it into memory and then slice out segments of it. So imagine all these little rectangles in here. We'll just cut them out and display them and duplicate them in our game and we'll make our character move. Just like old flipbook animations, you know, we'll change the animation based upon what's happening. So in the tile map folder, you'll see four different options. The one we want, you see packed. Packed means there's no spacing between each of these, but you'll see the one that's not packed. There's this one pixel between each tile. We want the one that has one pixel between each tile, but we want, and we, let's use the one with the, just use transparent actually. I think that will treat us better. So you want the one that's not packed, that has the gap between them and click that, drag it, go to Godot, make sure you're not expanded and drag it into the res area, your file system. So Godot just imported it and we can see it here. We could take this and just drag it into our level one and have this texture here. And you'll see in our scene, we've got a texture 2D with this here. And if we run our game, I should have just clicked run scene, you'll see this image is displayed. And yeah, we can make it bigger and warp it and do all kinds of things to it. But that's not particularly interesting. Aside from we know that it's in our game. So let's go and delete this. Okay. Now what we want to do is set up our level. And we'll do that by adding a new node for our tile map. So go in here, click, add node. We'll just type in tile map to easily find it. Click create. Now this brings up a whole brand new interface, which is why we didn't start here, because this is where things start to get a little bit more complicated. Over here, you'll see tile map. You'll see tile set. And then this opened up down here, which is our tile map editor. So we want to create a new tile set from that image we've created. So click this drop down and click new tile set, then click this area. And you'll see here that we've got properties for our tile set. Then what we can do is in here, we're going to go and add our image to the tile set. So you need to click the tile set down here. It says no tile set source created. Click the plus button. We're going to do an atlas. An atlas will represent the texture that we'll use for our game. So click into here and click quick load. And that shows the options. We have icon SVG, which comes with the game out of the box. And we have monochrome tile map transparent. Click open. The atlas's texture was modified. Would you like to automatically create tiles in the atlas? Click yes. And then Godot tries to automatically map them. Let's click this button to make it bigger. And you can see that things are a bit off. These orange lines don't line up with our map because we have gaps. So we're going to name this, we're just going to call this tile map. Kind of a generic name. And then separation. We're going to make it one and one. And now you'll see that everything is lined just nice. And it's a 16 pixel by 16 pixel grid. If we change this, you'll see it'll throw it off. So depending if you were using a different tile set, you would see how large is each tile set and set it accordingly. There's also an option for texture padding, which tries to help it. But since we have the spacing, we'll just leave it checked on. But that's an option that's there that you might want to mess with if you use a different tile set, a different tile map image. Okay, you might notice some of these are hidden. If you just click them, when we're in the tile set editor, it'll re-enable them. For some reason Godot detected them as I guess being disabled. So click those and just drag over it. Ideally that shouldn't have happened. It does it for empty ones, but it does it. It appeared to do it for some that have Sprites in it. So if you sell those faded out, just drag over them in the tile set editor, and that should make it better. So now we see here, they're all available. And you can just click the arrow button and select a tile, like let's select this one, and then draw a pencil. And we can just drag it. Let me zoom in a bit. And we're just drawing it. And that that looks pretty good. Now you may have noticed that's a little blurry. So let's try to fix that and make it not blurry. So what's happening is that our tile map texture is like it's scaling, but we don't want to scale because it's pixel art. So what I what we want to do is in the texture in the filter, it's using inherent, which we don't want. We want it to be nearest. So that says instead of trying to do some fixed fancy scaling, just do nearest. And that's an old that's a we're setting that texture for a tile map. So that changes it just for this imported texture. But let's change it for every texture we import in the future because we might, you know, add more images in the future. So in the general project settings, if you type in texture and click this default texture filter, see how it's linear? We want it to be nearest because we're making a pixel art game. So click close. And now if we were to go and we make this inherent, it's already setting it properly. And something else we can do is in the import, we can even go ahead and just re import that just to make sure that it's proper. But everything seems to be good. Now if we run our scene, we'll see our level is being drawn. Kind of neat, right? Okay, so we've got our tile map. Let's click that again. You have to focus that node to draw on and let's just draw a couple more things. So we'll draw an edge here. We'll draw this edge here. We'll zoom out a bit. Draw this a bit. Yeah, we'll draw some walls. Okay, nothing too exciting yet. But we've got some things drawing to the screen. And we'll start expanding level one. And we'll add some collision so that when the player, when we add a player that they hit this and they don't fall forever. And then we'll expand what's possible, then we'll add a level two. Let's go ahead and add a player that we can control so that we can add them to the world and interact. We'll start off by adding a new node to our level one scene. And we'll call it character body 2d. Click Create. This is a node that has physics and gravity affects it. It's what will be used for our player and if you had multiple players could be used for that or yeah. That's what it's for. You'll see here there's a triangle warning sign that says it has no shape so it can't collide or interact with other objects. Please consider adding a collision shape. We'll do that in a second. Right click on it. Add a child node. We're going to call it animated sprite 2d because we're going to make it so that our character can animate and click create. You'll see in the warning here a sprite framed resource must be specified. So over here in animation click sprite frames and new sprite frames. Click that and now you'll see down here it opens up a sprite frames editor for editing our sprites. What we want to do is click add animation. I'll just call it idle. We'll delete default. I guess we could have just used default. And now what we want to do is add a frame. We're going to click add frames from sprite sheet because we have our monocom room tile map transparent file from earlier with our spreadsheet and Godot automatically tries to detect and find things. So we're going to actually change that. We're going to say the size is 16 by 16 pixels. We're going to say the separation is one pixel by one pixel just like we did when we set up the tile map. Now you'll see everything is quite nice. Then what we can do is we can click and drag the tiles that we want the frames we want to add to this animation from the tile sheet. I'm actually going to unselect them because I was just kind of dragging around all the character ones. But let's zoom in a bit so I can show you some more. So you'll see here our character spreadsheet and it's blurry because we have to re-import it. Let's fix that really quick. Sorry. Go into here. Let's click re-import. Let's see if that's a little bit nicer. Yeah there we go because remember we changed the project setting that was an important step in doing that. So by going there to import and clicking re-import we can now see these quite a bit nicer. And look Godot even remembered the sizing and separation. So see this little buddy here with the horns. This buddy is going to be our character and we'll just set idle to this first frame and then these will be running and then these will be jump. I think these will be run these will be jump. This will be like success that'll be done. So we'll just click add one frame. It's a little blurry there but don't worry about it. Now we've got our first animation and we'll add more animations soon enough. Let's go ahead and zoom in a bit here. So there's our player. Let's add. Right click add child node and we're going to do collision shape 2D. This is what Godot's physics engine will use to determine whether or not the object is hitting a floor or another object and react accordingly. You'll see when we add it a shape must be specified. You'll see here in the inspector there's a shape option. So you can click down here and see a bunch of options. Generally for a player you do a rectangle or a capsule. A capsule is nice because it's got these rounded edges and just makes kind of hitting edges and sliding a little bit smoother. Then you grab these little control knobs over here and adjust it accordingly. Shift it down. But you know what this sprite is kind of shifted down. So I'm going to click that node for the sprite. Shift it up and then click back on our collision node and go ahead and adjust that. We can make it a little bit smaller. That'll add a little polish. Like you don't want it to be the whole thing. You want it to be just you know squeezed in a little. That's a little more friendly for your player and will feel nice when they're up against walls. So we've got a player here and if we click this let's just run our scene first. You'll see our player is just over here up in the upper left. We can't really see them. So let's go ahead and take click this. And when I click and drag it just grabs what's under it. But if you click the node and hold the alt key and drag it'll actually drag the node and its children together and that that really helps. So oops I started the wrong one. So we see our platformer over here a little character that's really tiny. And our game isn't set to scale. We'll we'll set that properly but our little buddy let's make them fall with gravity. So if you attach script to character body 2D it has a template that's going to add automatically. Well first before I get ahead of myself let's rename that node to player that will go make our script be more friendly name. I'm going to name it lowercase P player. I always name my script lowercase and snake case. But I don't think that really matters. I just do it for consistency and click create. Now in the script editor you'll see that Godot has a template for quite a few things already. It sets the speed to a constant value. It sets a jump velocity to a constant value. It gets the gravity from project settings. Let me just show you that. It's in physics 2D default. So you could increase gravity here but I think 2D works pretty well. You can adjust it as needed. And then there's already some code here that handles quite a few things. So it says if we're not on the floor add gravity to our y velocity. So that makes them fall our character fall handle jump. If you are exceptus press and not on floor then we set the velocity y to jump velocity which is negative which makes the player go up and then here we're constantly adding a positive value that makes them fall and then Godot handles some left and right movement. So this is actually good enough to start with and we'll refine it and make it better. But let's go ahead and see what happens. Do you see that our little buddy fell and is just falling through the world and falling down because we've got our script attached now but there's nothing for them to fall and stop them from just continually falling. So let's go back to the 2D view. We still got our character selected. I'm holding alt pressing and moving it and let's move them above the tile map that we just drew because we want them to stop falling when they hit the ground. And did you notice that they just kept falling. And that's because our tile map in our world doesn't have collision setup. So let's go ahead. We'll leave player right there where they are clicking the tile map again and in the tile set you click it to expand it and you'll see there's a thing called physics layers by default there's none. We're going to add a collision. We're going to add a physics layer and it has two things a collision layer and a mask collision layer is there's there's numbered values you can change them to strings to make them easier to remember but collision layer is what layer it's on and you might want different layers because maybe let me explain that a little differently like let's say you have a player and they fire bullets and player bullets can only hit enemies and they you know overlap with something else they don't do anything well then you would put the bullets on layer two for example and you would have them look toward maybe layer three with the collision mask so that it only targets certain objects on that layer when colliding it's kind of weird concept we'll get into a little more but for now the default one in one is totally fine and and actually i'll explain it more with an example after we set it up but for now just leave it one in one selected and that's fine now in our tile set here we need to edit it to define the collision properly so click in we selected the tiles that we're drawing with are these right here so you can click them sorry select them and so i dragged and selected them down here and i'm actually going to drag and select this whole square because we're using the walls too i'm going to click here into physics physics layer zero and you've got these options here you can add collision based upon the tile shape or you can draw your own like whether it's angle or just part of it and we're going to click reset to default shape so now if i click this tile there's no physics shape defined if i click here which was part of that selection that i just made you see how these are red that means they have collision associated with them so let's go ahead and run our scene again after saving and now you'll see our player just fell and they stop and that means they're colliding and we can actually use left and right to make them move we can use the space bar to jump so look at that just right out of the box gado we've got a tile map with a player and our player can move now let's take a quick moment to illustrate collision layer and collision mask so our player here if we click collision you'll see that they're on layer one and their mask is on layer one let's put them on layer two and click off layer one and run our scene now the player no longer collides with the level because our tile map collision is only on one it lives on one and it looks towards one if we set the collision mask to two it looks to collide with objects on mask two on layer two or say yeah on two but it lives on layer one if we make our player live on two and look toward one now they'll collide because the layer and the mask are aligned again don't worry about this too much if you don't understand it it's a more intermediate topic and something that i'm not sure if this tutorial will cover more but um you can get pretty far with just leaving it all on one one and as your needs for your game grow the needs for that will grow now so in the tile set editor there might be other objects we want the player to collide with so i'm just going to go ahead and select those as a group and reset to default tile shape you can even see that the f key does that quickly like all of these we just even if you know i think we're going to use them so we'll add them these blocks here they seem like they're things we would collide with doors maybe not door we would just overlap with so we don't necessarily want to have that be on the collision layer and let's see anything else all of these seem like it these all seem like it and by having a tile map like this and not having them all have collision you can add decorative tiles that the player doesn't run into like for example if i go ahead and um there's also just real quick aside there's a thing called one-way tile if you were to select it like let's go ahead and make this triangle platform i select them all click one way and yeah i'll show you this neat feature because maybe your game wants that so i had selected these triangles i'm going to select those and i'm going to draw that right there and i'm going to draw that right there let's go ahead and run the scene and i'll show you what the one-way does really quick so i can now jump through the tile but then when i'm on the top side of it i fall and collide with it now if we went back into our tile set those are still selected which is cool if you toggle one way off and save it might have to rerun it because of that changing that setting now i hit it and fall and i don't go through the platform so that just depends on your game's needs and like a given tiles needs but um i'm going to actually turn that back on because i think that's pretty useful for that tile type and that also shows that you know gado is re updating things in your running game but sometimes if you change certain things you need to rerun it for that just stick okay great let's go ahead and paint a little bit more let's add a decorative pipe up here just for fun we'll just kind of put this here put that here you know that kind of thing gado has some advanced tools for making tile layouts smarter and easier for this tutorial we're going to just focus on making you know handcrafted levels that replace everything manually so now we've got some decorative items in our scene sorry i alt tab to the previous recording and now you see i don't collide with the tree i don't collide with the pipe but i do collide with our platforms there's a couple things i'm noticing that i'd like to change so let's just go through them one by one player script i'm gonna hide and close this a couple things i'm noticing um well first let's yeah let's start by we have action just press it's using ui accept and ui left and right let's make our own input actions the comments here even encourage that so remember what we did we'll just do move left and i'm going to enter these pretty quick move right and then jump so you can add those quickly and then click the plus button and i'm going to make the custom controls so left i like the a key like w ast i also like the left arrow key and i also like the left stick to work and i like the left d pad to work so that gets us all the input i like and just out of the box by default i like to support three control schemes controller w ast and then jk for confirm and then arrow keys and zx i think by giving players options whether they have different keyboard layouts or um different needs based on their hands or how they like to play um i prefer to do that so let's go ahead and we'll do d pad right we'll do left stick to the right not the right stick that could be a little confusing we'll do move right i'm going to listen for input and use d to move right and i'm also going to use the right arrow key so we've defined those and then for jump we'll define a few things space bar that's just like pretty common we'll do z like i said we'll do j we'll do um the a button on the controller which if you scroll down that is um defined as bottom action sony cross or x xbox a and nintendo b so that gives us the basics there we can close that not delete ui accept and change it to jump and then delete ui left and change that to move left and move right and we'll do a little bit more investigating and i'll explain this code a bit more but let's you know one piece at a time go ahead and run the game i should have just run the scene sorry and then just verify it works okay i jump with the space bar i jump with j w ast works z works um tested with a controller if you have one that's feeling pretty good okay great another thing i want to experiment with is changing the speed so let's get the game running and leave it instead of quitting and we'll change speed to 200 and save it now move your player you see it's a little small a little slower and it's so zoomed out we're gonna fix that don't worry um you know so the player moves a little slower let's change jump velocity negative 200 player jumps less high right because they have less velocity being applied when they jump so change it to 300 and just make it feel good based on your intuition a lot of this sort of game design and game feel is based on intuition so i'm going to change speed to 250 and i'm going to change jump velocity to 400 and that feels pretty good an experiment with those values the next thing i want to show is gravity the way it gets it we showed where that's coming from this is how you get that value that's pretty nice um when you put settings there versus when you do and don't really depends really depends on what your project needs are if you have something that's shared across a bunch of nodes you could just put it in there and change it um there are many ways to go about that but uh don't worry about that for now physics process this is like process where it runs every frame like in our game loop but physics process might run even faster because it's simulating the physics so you know the game is calling this function a whole bunch if we put a print it would happen all the time delta is the time between the last time it was called and that helps make the game frame rate independent so like the amount of gravity that's applied when falling depends on how fast it it doesn't depend on whether or not the game is running slower so because the you know imagine you are an older computer it's running slower and there's 0.5 seconds instead of 0.1 second between things that's applied to this gravity calculation so the amount added to the y velocity would be bigger um delta time is a foundational part of game programming and there are times where you apply it times when you don't sometimes gado automatically applies it in certain places so um it's a bit more complicated but just know multiplying things by delta helps make things frame rate independent and we'll get more into that as needed but it might not even be something we cover too much in this video because gado kind of gave us out of the box what we needed and then we check if it's jump and we're not on the floor right that's it's nice how readable the code is in gd script we set the jump velocity to y and then input get access you may remember that we in level one said um is action pressed and that is pretty similar to this just press means that it's not being held because jump is you know just happens once um but get access says what is the difference between these two input values and um get them as a vector and uh or get the value and output it I don't know if it's a vector let's print a bug and see so it's zero I just press left and you see the values oscillating between negative one one when I'm moving right negative one one left and zero when not being pressed so yeah it gets us a numerical value that says which direction are we moving in and then we multiply time speed to go left or right otherwise if there's not movement then we move toward zero at the speed of the player so this slows the player down and uh it applies the speed towards that and like you know if we if we for example did it at the speed half the speed this would add a little bit of slow down a little bit of drag to our player just ever so noticeable and actually let's remove our print to bug here it's causing some noise um like divide this by 10 see how that like after you stop pressing the player moves a little bit you could even multiply it by delta if you wanted just to see what happens it's a really small value and after I let go my player keeps moving it's um you know kind of mess around that but you might want to do it divided by two and it just makes the game feel just a little bit better when you let go of you know a direction you're pressing so okay that's that um move and slide is a function that exists for certain nodes in gado that says take the velocity apply it move this object and check for collisions and if it does collide with something slide or stop motion based upon that and um let's learn about reading gado's docs because that's really important so in gado you can search help you can search for anything in here that's a function that exists or a class so if I type in move and slide it's filters down to character body 2d you can click open and you can read what this does moves the body based on velocity which is what the code gado gives us is modifying if it collides it will slide rather than stop immediately and you reading this is so important to understanding what gado is doing so let's click back in the player you can actually press command on mac and control on windows and linux and click and automatically just right there it opens it and you can read the documentation I can't recommend that highly enough if you already know how to code you'll be reading the docs because it's how you'll pick things up but if you're new to coding that's a really good habit to get into is instead of just right away googling something read the documentation it's going to be up to date accurate gado's docs are quite good um really recommend it so again this is code that gado gave us it's doing a lot of the box which is really helpful and it's good to understand it so I would recommend experimenting with it maybe try changing it around or inspecting the values but I think for now it's good enough for our 2d platformer so what is the next issue that we're being faced with it is it's really small like really small right someone wouldn't want to play a game if we made a whole level like I'll just quickly paint an entire level of of things right so we'll just in here we'll oh I have to select the tile map and um in here select the tiles we want to draw I'll just draw like an overlapping platform replace the middle parts with the middle parts and make it go down by placing the this tile here it makes it look like this is in front of it and add some kind of faux depth to the level which is cool and then we'll make it so that the player has to jump and then we'll go ahead and um think I think we added some stuff here so we'll just kind of make this block type thing happen and we'll connect them and make it a big old big old block and okay great let's run our game again I think I might have quit I can't remember and you know oh okay we might be missing collision on some of these so let's go into tile set it's um this chunky line so here oh yeah you can see where there's collision and where there's not so let's define some more collision something also that happens when our player falls off the map and they die we are left having to restart it from here we're gonna change we're gonna make a shortcut to make that easier but for now let's go ahead and okay we've got collision working and now I can run off the screen here you know see the character's leaving the screen let's add a camera that zooms in and follows the player and it's good though makes it pretty easy to do so what you want to do is add a camera so add a new node and add camera 2d and we can do a couple things right here we can drag this into our player node and it will follow the player and we can set the zoom to be two so we see here that the camera is here but our player is kind of over here so we can move the camera by pressing alt and center it on the player and that feels pretty like an easy solution we'll see how it works great now we're following the player and uh we zoomed in twice everything's bigger and a lot more visible that's feeling good let's change the zoom to three ah that's feeling pretty good I like three then we fall to infinity and that's an issue that will fix but let's look at a couple other things so you can add limits to your world so your camera like hits an edge and then the player would move but the camera wouldn't but we're not so worried about that smooth would make that smooth when it happens um but we can do something enable position smoothing this makes it move toward the player at a little bit of a speed that feels pretty good and we can even add some drag that'll just really make the camera just pretty quickly feel a bit better so you might notice the player is really jittery with this I don't know that's coming through on the video so we'll turn those off and run again yeah so jittery is it the position smoothing yeah the position smoothing is weird haven't run into that before but if you turn on the drag you'll see that the player starts moving before the camera does that feels pretty good um the position smoothing is weird I don't know I don't know why that was happening maybe we could adjust the value a little bit to maybe the 10 pixels a second you know I'm still learning too when uh doing all this stuff so sometimes it's a little bit uh you know I'm figuring it out too I don't know let's just keep that off and uh maybe that's something to learn more about but I think this camera is working good enough for now and uh yeah so we're zoomed in we've got a player they're moving around things that we need to do next are anime make it easier to have the scene reset make it easy to go to another scene maybe run and reach a door I'd love to add gem collection kind of like coins and mario um yeah but we're really making progress and you could go and click into your tile map and you know design your worlds and your levels and um add collision where needed and uh you know add decoration to your world and uh yeah just kind of make it fun and jump it oh yeah we'll also make the player jumping and movement feel better because right now I would say it does not feel so good um but uh yeah let's as our next part to introduce a new concept I would love to make it so that we have a level two that has a tile map that's different and then we can change between the levels because that will introduce some new needs in our game that are pretty important so so let's go and we'll just add a new scene and we'll do a node 2d and we'll call it level two we'll save it as level underscore two click save and if we run the scene we're basically back to where we were which is nothing you can click in the level one and you can actually copy this stuff which is cool so I just press command c or control c if you're on windows or linux you can just whoops don't select level one though select it's children and then you can just select it and paste it and we're in level two now we run this we've got everything there and everything's working and that's pretty cool and because it duplicated the tile map and we have our tile set with our tile map already defined with our collisions and such you know we've got everything configured we can go into the tile map here and we can select the eraser we can just erase the level and design level two it's got to be faster way to do this let's see rectangle select there we go so if you select the eraser and rectangle select that'll erase it then you can go ahead and click and we'll make this level like pencil tool that unclick the eraser place random tile that's kind of fun I don't know how that works quite yet but we'll just add this and it'll just be this sort of trash level for now but now let's go ahead and run level two our player falls and we've just got our kind of bad level level you may have noticed that level two that label we have in the upper left isn't showing anymore because in our world you can't see it but like way up in the upper left is where that label lives so we've got a couple things to fix and change right now okay so we want to get this label to display in our camera not in the world right like if we drag this here now you'll see that level two will show up in our world right there that's not what we want we wanted to display in the upper left of our camera viewport so we can do that add a new node we'll type in canvas layer that lets us draw it draws its children to the camera based on its position in our layout here so now if we go ahead and run the scene again just by making that level two label a child of canvas layer it's displaying up there and it sticks with where our camera is this is really helpful for the heads up display and you'll notice that we did this in level two but we didn't do it in level one so let's quickly go back and do it it's good practice you just drag it in make it a child run it again and we make sure it works so that's one issue that I wanted to fix the next issue is that this player while it shares the same script player dot gd this player in level one is fundamentally disconnected from layer two like if we go ahead and change our sprite our animated sprite here to use a different sprite like click into here select this godot does not remember it right it's 16 by 16 with the one separation if we made this player instead be this little horned friend an ad frame oh it doesn't like something there 16 by 16 one pixel separation something seems off there but there was like a part of the foot selected let's try that again yeah that's better so delete the other frames and then go ahead and run level two so level two now we'll see the player is this little skull with horns then if we run level one oops that's level two let me refocus level one in the running scene this player is now just our normal little buddy that might be a neat feature if you wanted to but it'd be better to change that with code and the properties of the player are just now fundamentally different like the collision layer the the maps uh sorry the mask and the layer they're disconnected so what we want to do is make it so that we can share the player across our different levels and our different scenes and all we need to do is here we'll delete this node for the player save it and then here in our player right click and say save branch as seen and it automatically wants us to save it as player so i went ahead and did that and you'll notice its children are gone and now there's a movie clapper a film clapper which is to open in the editor and we still have the script associated so now if we click open an editor and we've you go to the 2d viewport here's our player i have to zoom in so we can see them because of so how tiny it is but now you'll see our players here and what we want to do actually is take all this select everything hold alt drag it back to the center here and grab this little cross actually select everything i undid that and just select the sometimes this is a little tough of an interface okay select the top node hold alt and drag that drags the center cross the sprite and the camera to the center viewport before the player was all shifted to the right but we can just keep the player right here and have them exist nice and in the center and we'll see that something else is a little shifted the camera is so we'll select the camera here hold alt and drag it now the camera is centered with the player it could even be shifted up a little now everything's centered back in level one you'll see player is now centered but we can actually go and hold alt and move the player this way easily so we're just dragging the player around and we can place them at the start of the level because this is where they'll be when we run the scene so we went we created a branch of our scene and saved it as a scene and then we instantiated a version of it that we can then run and then now in level two all we need to do is click this link or the shortcut and you can instantiate another scene within your game so i'm choosing player dot tscn and then you can just drag them to the starting place run the game and it's the same player and we can go in here now into our player scene and manage the player script we can manage their sprite we can go ahead and change things with ease and that makes such a big difference and you'll do that with all types of things all types of objects in the game and uh we'll do that a little bit more but now let's go and we'll change it to the little buddy it's got the weird side but that's okay we'll just drag it to the left for frame one rerun the scene and we'll see it's the horned buddy and now if we were to quit and run level one again it's the horned buddy so now it's shared and that's ultimately what we want so go back delete the little horn guy and um save our player and so we've got level one level two we've got a shared player now let's make it so that you can change between go from level one to level two when you reach a door before we jump into switching levels let's take a moment to pause and make a to-do list i'm going to open up a text editor called sublime text and i'm going to start making a to-do list because i'm having trouble keeping track of everything that we want to do so we'll do to do we'll do done so we want to add doors to switch between level one and level two we want to i'm just going to run the game make the player animate based on the direction they're moving and jumping i want to add some collectibles that are tracked across levels collectibles tracked across levels um export name and upload to itch.io and i think that's good enough for a basic platform you could go and add enemies and things like that but i think for our case this basics will work and as more things come up we'll add them to the to-do list you know oh you know we'll add some other little polish like ability to we'll add setting for full screen we'll add s effects for jump um music track that would be really great differs per level we'll add a setting for full screen that players can toggle we won't necessarily save it to the disk um that's more advanced and then we'll add a quit button but only on desktop we'll say hide on web and then let's also um make escape go to main menu at any time from any level and then let's add a level three to show how easy that is and then when we're done we'll upload it to itch and what we've already got is main menu levels with tile maps player you know we've done quite a bit so let's go ahead and add doors to switch between level one and level two we'll start on level one and what we want to do is in level one you can actually do it as a child of the tile map or you can just do it um above it i think it is fine either way we're going to add a new node called area 2d and this will be used to detect collision with the door so we created it here and there's nothing there and you'll see this warning remember in the past it always shows it when it's incomplete it wants us to add a collision shape 2d so go ahead and add a collision shape 2d like we've done in the past we'll make it a rectangle and that's pretty good okay so we want to display a sprite for the door so go ahead and add an animated sprite 2d we might not animate the door but this will be a pretty easy way to go and handle this similar to like we did with our player so we added a sprite frame and we'll go ahead and add default and then here we'll open up our tile map like we did before we'll set the size to 16 and we'll separate them by one pixel and there might be multiple ways to do this but i think for our case we'll just go and do it the way we know it and here we'll just add a frame and added the frame door now you can see our doors here if we click into this collision shape it's a little bit big and we're doing this separate from the tile map collision layer because we want we don't want the player to stop moving when we hit the door we want to just know when they've hit the door and then we'll change the level so now we've got this door and it's quite a bit more aligned our collision shape we can then zoom out a bit remember hold alt and drag it and we'll put the door over here on the right to encourage the player to go over and now as we're dragging it you can see it's not really locking to anything so you can click here and we can do a couple things we can toggle smart snapping and we can show a grid and enable the magnet icon there says snap to grid so now it's snapping to the grid and feels quite a bit nicer here also let's rename area 2d to door and if we wanted to add a door animation you know we could but we haven't gotten to animation yet so we're not going to worry about that but let's go ahead and wire up a signal that deals with our door area 2d so area 2d has a few different signals area entered body entered body exited area shape entered body shape entered we want to do body enter because when the the player body enters in this blue rectangle of the collision shape we're going to want to change levels so let's connect it this signal to our level one script and we'll just say we'll just print a bug and say player entered door and then run this scene and then move the player over there and then do you see player entered door every time we go in that gets triggered it's actually getting triggered twice so that's kind of interesting i don't know exactly why that is um there's something uh kind of interesting about that i don't know ah sometimes it happens once sometimes it happens twice i guess it depends on if you overshoot it um but for our case knowing that they entered is fine and then what we'll do is instead of changing to main menu we'll just go ahead and change the scene to level one or level two because we're in level one and godot helps us with autocomplete there and then now if we run just this scene oh i ran level two huh so for some reason it went and changed it automatically now why is that i think i might have an idea let's figure it out if we do print to bug body and just have it output what the body is we'll learn quite a bit so it's saying that the body that collided with the door is the tile map and we don't want that right we only want to follow it when the player collides with it so that makes sense why it wasn't working so we can say if body equals equals and then we can actually do dollar sign player and that references our player node so now if we rerun this you can see it didn't change the scene right away but then when we hit the door with the player it goes and changes to level two let's talk about this more in depth so body is whatever entity in our 2d worldview is colliding with the door the level the tile map level that we added collides with the door and our player collides with the door in our script code we want to check and say if the body that entered the door is the player then we change the scene only if it's the player and we can reference our player node here which is an instance of our player scene with the dollar sign and that says specifically is it this player that entered the door does that make sense um we only want to change the scene if it's a player that enters the door if you had an enemy that was walking by and they walked past the door you wouldn't want to change the scene so we go and we check and we ensure that the object entering the door is our player and there are various ways to check this but I think this is pretty clear and works you can see if we type dollar sign Godot will start to auto complete the nodes in our scene for us so that you can get player and you can even get the player's camera and you can modify the cameras the player's camera and that uh let you easily access things and set properties on it which is uh really really helpful but for our case we just want to just ensure that the body is our player so that's a door let's go ahead and add a door to our level two and we can even let's make our doors reusable just like we did with our player so we'll go ahead and click this and we'll say save branch a scene we'll call it a door and then we'll open the door scene we'll open it in 2d view and it's way over to the right remember we have the same problem with the player so select it all dragon select it and then bring it back to the center and recenter our door and this just lets us have the origin of the door be right in the center and it centers it here now back in level one it moved it because we moved it but now we can just select our door and drag it over here just back to where we had it that's just one of those little things that when you create nodes in your scene move them around and then you convert them to their own scene you sometimes have to reposition them that's fine let's go ahead and um notice a couple things when we click into door here our signal is not connected and in our level one we lost our signal connection and that's okay it's because we converted to a scene so just click connect again and you can actually pick an existing function in our script because we already coded it so you can just go in here click select it and connect it and now it should be working right again so we'll click start we'll run over jump to the door now we're in level two let's add a door to go back to level one and then we'll when we eventually add level three that will be nice and you know we could even like just for fun we could add a label and that's going to be at zero zero so let's zoom out drag it over in here we'll just add a we'll call level two so we know our player knows it's kind of fun it might be pretty pixelated um let's just run just the scene sometimes the way the text scaling works is a little funny yeah it's a little pixelated but uh you know what I don't think I really mind it I think it's kind of uh charming in a certain way if you had a different font you could go and make it like a pixel font that would make it look a lot nicer but I don't see any options to make it uh look better and and why this is happening I think is maybe worth talking about just a little bit is you know we have our camera zooming in and the font gets zoomed in on and doesn't have any sort of scaling applied to it so it's just zooming in on the pixels of that drawn text and uh that's you know yeah what are you gonna do about it it's uh totally fine we can even drag the label as a child of door and when you make a note a child of something and you go to the scene it's no longer a child in the parent like scene it's just there in that instance of it and that's actually pretty useful so let's select door controller command c copy it go to level two paste it and now we've got a door and our door is gonna be positioned way over here so grab it hold alt drag it and we'll just say turn on grid snapping we'll just drag it here make it look nice okay we'll shift it over we'll make this level one and then our player here is gonna fall and collide with the door which is an ideal so um and and we could make them kind of come out of the door and move but I think it's actually a little easier to to make them just kind of spawn to the right of it because if we spawn them in the door it's gonna trigger the body entered and we let's not get into the advanced topic of you know handling that logic I think that's something worth doing but I don't think it's worth doing quite yet and we'll just let's make that a little closer and we'll move this one down just a little closer and we'll run this scene we'll see what happens so our player spawns here we go into the door nothing happens that's because we need to wire up the signal again right it's looking like it's connected because we copy and pasted it but it's not connected quite in the right way so you disconnect it and then you can connect it again and we don't have a level two script yet so let's go ahead and add a script we'll call it level two we have all this stuff here we can delete it and then now we go back to the door body entered connect and maybe we should do the door stuff that would be fun let's put it on the to-do list you know switch level to door and track readiness to enter that'll be a little more advanced scripting and we'll do that a little bit later on but let's connect this and from our level one script we'll just copy all this paste it but instead of changing to level two we'll go to level one go ahead and rerun level two and we'll see what happens so great we can jump around click that and it spawns us at the spawn point of level one not our door and that's probably okay right like maybe if you had a game that was like a metroidvania type game you might instead have a way to track like which door a player is entering and going back into but I guess for our case for Mario style game you would just want to spawn them at the beginning of the level and they would move on so um yeah that's just a behavior that we've got here we'll make it so that um we'll delete the to-do for handling level readiness in the door I think if I made a video that was like how to do metroidvania and you had doors and you were entering an exit and that would be that'd be its own video because that stuff gets pretty complex so okay let's look at the to-do list right this is why to-do lists are really helpful you can go and keep track of how you're going so great we've got doors that switch between level one and level two that's pretty cool and I like to go and just run the game again test it make sure it's feeling right right yep we can go ahead and play our level that is good stuff then what we can do there is we'll add a level three at the end we'll do that at the end now when you press escape in level two we'll start with that because I think I think that's a quick thing and sometimes it's nice to just do quick things so if we run level two and press escape we don't go to the main menu if we run level one and press escape we go to the main menu so all we need to do here is in the input event you can just copy and paste it run it now if you press escape and level two it goes ahead and does that and that was simple but we've introduced duplication in our code some duplication is fine right like this on-door body entered and connecting the signal the level changes based on that so you know it's it's not the best to duplicate this code because maybe we want the logic to be more complex but it's not too bad but this input event where we return to main menu that is the same exact code in two places that is usually a sign of an area where we can make the code better and we'll make this better by introducing one place that this code lives and gets checked against every scene while running and the way that this works in Kadoa will also be used for keeping track of things like for collecting gems or how many lives the player has and that sort of thing right so let's go ahead and go up to project project settings auto load and then in here is a whole new interface and what you want to do here is just type in a node name and we're just going to call it global for now and click add and it brings up this interface for creating a new script we'll call it global dot gd click create and by default it's enabled as a global variable so it is a area of code that we can access as needed which is quite nice and it'll always run when our game runs so we'll click close now global has been added to our game you have to double click it down here and open it in the script and let's just do some learning to see what happens I'll do print debug global ready save it and then we'll run our game again and you see global ready was triggered and then main menu now when we loaded level one global ready didn't get called again which is great that is what we want now if we in here add print debug global process save that that gets run every single time like our other process so that's helpful but we don't really need that um also print debug is like printing which we've been doing elsewhere but it only does it in the debug mode of your game which is like while you're working on it but then when you build your game and share it with players this won't happen so I think this can be nice to keep in sometimes to help you um know when something's ready and being triggered so um print debug is really helpful to help you the game developer so what we want to do is in level one and level two we'll cut this out so select it and you can press control or command x and then just oops go back into uh global dot gd you can't switch to it from up here because it's not a scene so just go back paste it in here save it and then in level one we've removed it in level two just get rid of that input event now run the whole game again we see down here global's ready if we press escape it switches to main menu but that doesn't really matter because we're in the main menu so it's not a big problem now if we're in level one we press escape it goes to main menu and then if we go to level two and press escape it goes back to main menu and now our code only exists in global dot gd so that's pretty handy so we'll do more with global gd eventually i also just realized something that we want to make better in the game which is um we want to as part of our polish uh we want to make it so that we focus on main menu buttons on launch for controller support for controller and keyboard support because right now if you launch the game and you press the space bar or use your your controller nothing happens but we want to make it so yeah you can click the start button but we also want to make it that you can use your controller and your gamepad for that and it's really easy to do so we can just go ahead and do that but we'll do that later so we've got a couple things animate the player based on movement and direction and jumping that sounds really good let me actually save this to do file because i keep doing it out of habit and uh yeah now i can save it so let's animate the player based on movement and direction and jumping so we'll go back to player and we'll look at our player right here we'll close this make a little bigger we have animated sprite 2d and we have idle let's go and add a new animation and we'll call it run click here select this again i don't know if there's a better way to do this having to keep selecting it and set the separation and everything um but this is what's been working for me still got any ways to learn so we'll click this tile we'll click that tile and we'll just make that the run loop and you can click this play button here and see it run and you can even change how fast it goes or how slow it goes by changing this value i think five felt pretty normal and maybe these the run loop that i'm showing here maybe maybe it looks funny maybe i picked the wrong frames um yeah let's open this again and just let's zoom in a second and look at it let's make sure i picked the right frames so do you think that third frame would look good i think so okay let's add that one in too so again we'll just go and click into that third frame and now we've got it okay that looks quite a bit better and let's see how it looks at six fps yeah that looks pretty good so now we've got these two animations and we want to play them based on what's happening so go ahead and save that and then click to open our player script and we'll drag this down but keep the animation we can't okay we'll just drop it down we can reference it as needed so what we've got here is our old script from the player that was added by godot i'm going to clear out these comments just so we can have some focus and here we have direction and remember direction was either negative one zero or one and if it's zero we move towards our velocity otherwise we start running so then all we have to do is we can say animate a sprite 2d and we reference the node with the dollar sign and you can just say dot you can say play and then you say what animation do you want to have play and we're gonna go and say when moving we'll do run otherwise we'll play idle there might be some problems with that code but we'll go ahead and learn so that's working right and then we stop and the player's idle but do you notice anything that's wrong i noticed a couple things one is that the feet are kind of hidden at the floor of the level and when we move left and right the player doesn't move accordingly so let's go ahead and fix those two things let's bring this debugger down hide that the output and let's do a couple things we'll say we'll say if direction is equal to negative one we'll say animated sprite negative one represents left we'll say flip horizontal is true because by default right our player is facing to the right but if they're moving to the left we want to flip it to the left so we say flip horizontal true and then we'll say else false let's go ahead and see what happens in our running game and we see okay that's working when we jump running is still happening so let's go and add a jump animation we'll go back here to our animated sprite 2d we'll click into the animation into the sprite frames and we'll add a new one new animation called jump same process as before and then we'll zoom in in this frame there's one frame here that looks really nice for jumping we'll just add that frame and it's just one frame doesn't animate it doesn't loop or do anything like that let's bring these down expand this and then what we want to say is if jump and not on floor we jump and we add the velocity here we have the movement but what we want to say is at the bottom after all this code is processed we'll say if not is on floor override what was ever set before you know because like maybe this is true it's set to run and maybe it's flipping horizontally and that's important we still want that to be processed based on the direction of press but if we're not on the floor go ahead and do jump now if we go back to our game and we're moot we're moving and we jump that's not working maybe we need to rerun the scene because we added a new animation oh god what happened there oh i ran the player scene so the player has gravity applied and it's just falling so let's go back to level one and click run scene and now if i jump you see jump is is happening instead of running great if we're facing left and we jump its face is in the right direction and when we stop moving the player just looks right at us maybe you would change the idle animation to instead be facing left or right that's ultimately up to you and what you want so now we've got basic animations happening for the player um another thing i just remembered we want to add is quick level reset let's go ahead and just play with that some more let's find a long stretch to run oh i just i went to level one really quicker level two and um yeah we can run back and forth that's feeling pretty good but like i noticed earlier the players feet are kind of hidden in the level maybe if you had grass like decorative grass that'd be nice but for our case it's kind of doesn't seem good so let's go ahead and change that and the reason why this is happening what's the reason why this is happening let's um go ahead and in our animated sprite 2d we'll select idle and we'll look at this we'll look at run we'll look at jump jump is good right this collision sphere is below the feet of the player so that feels pretty good but here the players feet are below the collision sphere so what you can do is you could grab the collision shape 2d and drag it down or we could drag the player sprite and just drag it up so now they're aligned do you see how the bottom of this blue oval is aligned with the player's feet now if we go back into gado we can see the player's feet that just looks a little more natural right it looks like the player is running and um that's that's definitely preferred so um yeah we got the player animating that wasn't so painful was it we'll just recap you click in the animated sprite 2d the gado inspector is really giving me a hard time right now um let me minimize sprite frames you click into here into sprite frames then you go down here into the sprite frames area and you can define your animations then in your code where you have the animated sprite 2d you can just go and say play certain animation and that will do the trick so that's player animation not too bad now let's do collectibles and we'll keep track of that data across the level all right so in our tile map i just double clicked it and opened it might be a little hard to see but there are little gems there's this coin looking thing we'll call it a gem let's make it so you can collect the gem and then we'll get into sound effects so just like we did with the door we're going to create a new scene and we'll say other node and we'll say area 2d just like the door we're going to call this gem and we're missing a collision shape and we're going to make it a rectangle for now we're going to add a child though we'll do animated sprite 2d again just because that makes it really easy to add animation if we want it and to just define the sprite frames so click that add new ones we'll just do default click in here load that okay and then we'll zoom in and we'll pick one we'll pick that gem add one frame and now you can see that we've got this gem we'll save gem.tscn and let's just make the collision shape just a little bit it's got magnetism on so there we go turn that off and just pull it in i'm going to keep it a rectangle you could make it a circle or an oval but uh i think a rectangle is nice because it's just a little more forgiving than the player and i've got about a pixel of space on either side and we've got our gem now what we want to do next is put these gems in our levels so here's level one and all you do is the chain link click gem open and then you'll see at 00 our gem was added so alt click and drag it we'll just add some gems here like there's that let's take our player we'll move them over here and then you can with your gems you can press control or command d to duplicate and you can add them to your level and kind of encourage the player where you want them to go and lead them places we'll put one here one there put one there put one down here one here one here and then that's uh that's gems displaying in our levels so go ahead and run the level but then when we you know hit them with the player which sometimes can be a little tough nothing uh nothing happens well that's because we need to wire up the gems to keep track of themselves and to hide themselves when they're collected so up here in our scene area let's go whoops to gem and we'll do a couple things we need to attach a script gem dot gd is great we'll go ahead and clear this out because we don't need any of the default code there here and we'll wire up our gem the body entered 2d and we'll hit connect and we'll say on body entered we want to do a couple things we only want it to we want to make sure that it's a player just like before so we'll make a comment and we'll say one make sure player to add to total collected gems and then we'll say three remove from scene so let's do it in that order we'll do print to bug body save it and we'll run the get run the level and we'll just jump up and see that okay when we see that it's the player now we don't have a dollar sign player that we can check so what we can instead do is inspect the properties of the body which we know is a character body 3d but we might even be able to do something like if body dot name equals equals player because we named it player that's one way to go about that then we'll say print to bug player got gem run that again great player got gem and if we then put a gem on a like it collided with another entity like an enemy that wouldn't happen and this depends on the player being named player in your scene so it's not the most resilient but I think for now it does the trick because it's clear it's obvious that's what we're looking for at the beginning now we're going to add to total collected gems which is something we don't have yet and we haven't really gotten too much into variables so open global dot gd and then here at the top we're going to type var var shirt for variable and it represents some sort of data that can be changed and used and displayed modified it's it's it's how you store things and we're going to call that variable collected gems no we're going to call it gems collected and then you can do an equal sign to assign it a value we're going to assign it to zero and then here at ready we'll say print to bug gems collected and you can reference this variable in various places so now we run our game and we'll see zero gems collected in our gem script what we want to do is when the player gets a gem we're going to type global with a capital G to reference our global code there and you can do dot and we actually have access to gems collected and we can print to bug that just to show that we can get its value okay we got a gem twice actually because we jumped over and then fell on it and our gems collected is zero so what we want to do is when a player gets a gem we want to say global dot gems collected equals global dot gems collected plus one now we'll do that above our print to bug and we'll watch the value change so I jumped again when we hit the gem going up it became one gem collected then it became two gems collected I jumped a second time three and four now we have to do step three we can remove it from the scene then it won't count it twice so to do that and you do q free and that says when the game is idle and it's currently finished what it's doing remove this node from the scene so then it can't be collected again now if we go back to our game see the gem went away now we have five gems six gems seven gems eight gems great let's run our game from scratch again from zero and now we're collecting gems you can see down there in the lower left the numbers there so let's go ahead and display how many gems have been collected excellent so we can get rid of our print to bug we can also instead of doing well before we get rid of print to bug let's hold on our horses you can just do plus equals one that's the short code for an item is assigned its value plus another value you can just do plus equals and if we run that again oh it's going to run the gem scene if we run our game again and collect the gem everything still works so that's just a little shorter and you know just just that's how i would write that line of code so clear that all out clear out the player got gem because we don't need that and we're feeling pretty good about that now what we want to do is let's add some gems to level two because then that'll keep going with what we're doing so here we've got all these gems in this list let's put them in a node so you can just type node and a node is just a generic collection of things it doesn't do anything special it just puts them in a folder and i like doing that so we'll just call it gems great now on level two add another node call it gems and then we'll click the chain link and we'll do gem and we'll do open it added it to zero zero so alt click drag it and we'll just we have our little playground level all duplicate it and we'll add two gems now if we run this level we're not print debugging but i'll show you another way we can see the value we collected two and then we go here we'll collect some gems and gems will respond when you change levels but let's learn about something new while we're making our game so when you're running your game you can actually click into remote here you can click into global into the inspector you can see gems collected here so this remote tab is the running game kudos able to look at the data and tell you about it so if i go here see this seven here if i get this gem now it jumped to eight so print debugging while nice especially to see when something happens if you want to look at data in your running game you can go into this remote scene area and look at it but when you stop running your game it disappears and goes away because our game is not running we also want to have a gem amid a signal that somewhere else in our code can listen and go oh okay a gem was collected let's update the display of them accordingly so we can actually add a signal and we'll call it so just like we hooked up signals from existing nodes like you know on body entered we're going to find our own signal and we're going to call it gem collected and all you need to do here is type gem collected dot emit with the parenz because it's a function and then now other parts of our code can listen to see when a gem is collected and react accordingly so let's go to level one and let's look at our view here so we've got gems and if you click into node you see now there's a signal called gem collected isn't that handy so then you could go and double click you could connect it to level one well before we do that though remember when we added our heads up display with the canvas layer and we have a label that's level one we'll just call it level we'll call current level just so it's more clear now let's add another label called we'll just type in some texts gems collected we'll just call it gems colon and we'll put zero there and we'll drag it over here just kind of align it and make it look nice and we'll call that label gems then what we can do is we got a couple options we can wire up these signals to say when gem is collected we'll go ahead and submit a signal and then we'll listen to it and we'll update this text according to that so we can actually call I think I'll call it gems label just to be clear in our code so then let's actually go back here to this signal double click connect we'll just put it in the level one script and we'll say remember in our inspector here we had this called canvas layer let's change that to HUD that'll make it easier to reference that's short for heads up display and we'll just say HUD slash gems label dot text that's a property of the text value within it is equal to global dot gems collected and we are going to actually make it gems colon space and you can plus in that gems collected is a number so we can turn it into a string and add it to this string so that it displays properly and looks nice so let's go ahead and run level one and collect that first gem see how we have gems zero in the upper left okay we collect this first gem and now we have gems one let's collect a second gem well that's not updating our UI even though we are collecting that gem because we've only wired up the signal for one of our gem notes and that is when we have all of these duplicated gems that is something that we need to figure out what to do so we've got a couple of options and um I think the way that I'd like to go about it is wiring up so here we manually collected gem or we manually connected gem collected to our level script I'd like to disconnect that and we'll connect it manually because we want to as we add new gems we don't want to have to connect each one to the on gem collected and you can actually see something else that is kind of duplicative is we have on gem gem collected so let's get rid of that first one I'll just call it on gem collected and then what we want to do is on our ready when it says level one's ready we're going to actually go and loop through each of the gems and wire up that gem collected signal with code instead of doing it by hand in the inspector so we'll say is dollar sign gems and then there's a way to get the children and that returns an array which is a list of nodes that are its children and we can actually say for gem in gems and then we'll say gem dot gem collected dot connect so remember we were connecting signals in the inspector by clicking now we can actually connect them via code so we say when the signal gem collected occurs connected to and we'll connect it to our on gem connected collected sorry connected and collected sound very similar so you could just go ahead and pass in this function name into connect but you don't put the parentheses here because when you're writing code especially gd script and this follows in other languages too the parentheses say call this function but you can reference a function by its name and it won't call it until later when connect when this signal happens so if we go ahead and just save that and run our game run level one now we can go ahead and say okay we connect we collected some gems and see how gems is updating properly that's because each of these gems that are in our games level got connected to on gem collected which then handles updating the HUD accordingly now there are other ways you could go about this but I think for learning purposes to show connecting signals by hand to then connecting them via code is and and having a dynamic list of them is really helpful and you know you might even do print a bug gems dot get children just to see what that looks like right let's do it together and just go ahead and look at what that looks like so you can see what a list is so right here is what it just printed so an array is a list and it's usually denoted by brackets and each item within it is separated by a comma so you could have an array two that's like one two three and in our case we have a gem we have an array of the gem nodes and so this says for each gem in that array that list run this code on it and this gem here that we define you know that's something that we type we could name it you know like you know we can name it whatever pool and then if that wasn't even pool we just want to correspond there and so now we're collecting the gems but let's go ahead and run level two and you'll see that oh this is going to run level one there we go we stopped that if we collect these gems we don't even have the gem count there so it's not going to update and display and we're not connecting those gems properly so we've got a couple of options here as always we can do a couple of things and it how we go about it is ultimately up to us but I think what I'd like to do is see we have this HUD here and we have gems labeled you could copy it paste it copy this code again on ready to manually connect it and add this here but that quickly becomes pretty brittle because every time we make a level we have to make sure we wire that up properly which that's not what we want to do so what we can instead say is we can take our HUD and hmm how do we want to go about this it becomes this is where you know gado and making games becomes a little bit more complicated one option is that we could have this level one and level two script because they are quite simple we could have them share the same script and then that would mean that the same ready works and I think that feels pretty good to me and then we can make HUD a shared resource accordingly so let's go ahead and do that so we've got our level one script we can go and we actually have to do it down here and we'll rename it to be just level level and now here gado automatically connected level when we renamed it via the resource manager it automatically changed the one that's connected to level one and we can say here we can export a variable and we'll just call it level none and let's see it needs an initializer so that's saying you can't just say that without assigning an initial value so we'll set it to zero and what this does is that when we attach this script to any number of levels which we will do we just want to be able to know which level we're in so that we can set the level HUD and we can set the um this print even and we can set which levels to change to accordingly so by saying export variable when we click into level one here this node now we have a number here called level none gado automatically translates that so we're going to change it to one and this only changes level none for this instance of a node using the level script now if we go to level two which you'll notice that our door changes to level one um but other than that it's pretty simple so we can actually delete the level two script and it warns us that it's connected and we know that and that's okay and here we can even detach the script so it's not there now let's attach a script and instead of having it create level two we'll connect level dot gd click load and now you'll see you when we click level two then in the node scene we've got our level none and you can change it accordingly so now we have one script level that's sharing the functionality accordingly now there's a couple things that we want to do it's always going to print level one ready so if we run level one see it says level one ready down there in our print now let's run level two and see what it prints level one ready let's make it so it prints our proper level number so remember before we did this we added some strings together gotta convert the num to a string and you can then come concatenate is the fancy word for this so you can concatenate strings together to compose them so now see down here level two ready and we've got the um HUD showing the level number is working properly so um because those are uh our canvas layers different we're going to actually make HUD a shared node and reuse it in our levels which is really fancy but really really nice um but there's something else that we need to fix because if we go to this door did you notice that it's just automatically loading level two because we have hard coded the game to always change the scene to level two any door will change the level two so there's we've got options here we could make the door and we could set the property so how how did we work the door right let's open here and door is just uh has it's an area 2d so uh we have that event and we say on door body entered we could connect we could we got a couple things we can make it a door go to a specific level um or we could always say you know the door of a level goes to the next level let's make it so that doors have a property of which level they go to so click into door attach a script we'll call it door dot gd and we can remove these and again we'll do export bar and we'll call this um you know level like a door goes to a level and we'll just assign it um we can make it a we've got a couple couple options let's go ahead and we'll do the simple thing first which is just we'll make it an empty string and then um we can explore some other options potentially but for now just make it empty string then if we go to level two and look at the 2d mode and scroll in and click our door you'll see that there is a level field here and we want this to go to level one so if you copy if you right click the level one scene and you say copy path and then click into here this new level exported variable and paste it it says res colon space space level one dot tscn so go ahead and save that and then click our level script which is our shared level script and now it says on door body entered it sure would be nice to know the door here i'm not sure if we can get that so let's quickly see something um so we have door here and it's a node and we have on body entered we can double click we can't double click that we can right click and click edit i just want to see if there's a way to know the door that um that we're having connect there's not so what we want to do is in addition to our export variable for level let's add a signal to door and we'll call it um entered and that will emit a value of the level we want to switch to and then we'll connect the door body entered now this is we're editing the instance of the door we actually want to edit just the scene so i clicked into the scene and we'll see body entered door and we'll say here we'll call player entered and remember in our code we check if it's a player and um there were a couple different ways we did that right oh i think i may be deleted the part of that code but um where we were checking if the body is of of type player but we'll go ahead and we'll say if body dot name equals player so we have to have our player be named player we'll say player entered emit and then we'll pass the level variable that we have set so then we we've just connected a signal to emit a custom signal that has the data that we need in our game and then we'll wire it together so let's go back to level two we've got our door here and we're going to actually disconnect this on door body entered and we're going to reconnect it on player entered and we're going to say it's called on door player entered we don't need to check that it's a player because we know that it's a player and it automatically adds this level parameter which is the value that we emitted here when the body enters because each door is now going to track which level it should change to and when a player enters the door we need to know elsewhere in our game code which level to load and instead of having the door handle switching the level we'll have the level handle switching levels so we're taking the signal and we're communicating upward now we're going to go ahead and we'll delete on door body entered because now we have on door player entered and instead of hard coding it the level two we can just say level so and this is indented one extra so now our level script is responsible for handling switching levels and this is preferable because and maybe in the future as your game gets more complicated somewhere something else would handle it but for our case now we know that the level handle switching it and I guess you could make the case for switching the level here but it just to me that just feels like not the responsibility of the door the door just needs to tell communicate upward hey something you know players entered so I know this we just went forward quite quickly but we're kind of piecing things together so that we can share this level script which will then let us share the gem collecting in the HUD so let's go back to our 2d view and we're in level one now let's connect this door to go to level two so we'll disconnect this one see this one that's yellow that means that it's connected to the root scene that you know the shared portion of every door has that call if we double click it you see it goes to the door gd script but anyway let's go to the inspector for our door we want the door in level one to go to level two so you right click copy path and paste it in there and we've got level two there let's see if that works go ahead we'll run our game it's going to run level two and that's okay all right we've got an issue here it's saying invalid index text on base null instance with value of type string so it's trying to get head HUD gems label but we're in level two and you'll see we don't have that there so we can actually copy and paste gems level and we'll go back and we'll make this less duplicative but let's also rename this to be current level rerun the game because it ran into an issue and let's go in that door see now it brought us to level one let me move my mouse cursor okay that door to level two didn't work so let's figure out what's wrong there so that was in level one and we set our door to go to level two seems like it should have worked but let's see what happened on door player entered maybe we need to connect this uh-huh and this sort of like you know forgetting to connect things that's something we could remedy with a script but for now I think this works well for our needs and maybe when we get to level three let me make a note we'll um connect door player entered signal with code just like we did with our gems so let's go ahead and run our game and make sure everything works we'll start we're running we've got our gems connect collecting great that's counting properly I just fell off and there's no good way to reset so we'll add that in a second um go there level two great um gems was updating properly because we added that you know we added that label note accordingly but did you notice that when we went to a new level even though it's keeping track of our gems it shows zero gems until they're connected we'll want to really quick here we'll say um HUD well we'll just say set set gems label we'll define a custom function ourselves that does this code so then we can call it from multiple places so up until now we've primarily been using functions that Godot comes with or that Godot generates but when writing scripting code you know you often want to have something happen multiple times based on different logic so when the game is ready we're going to set this label to however many gems you have collected and then anytime a gem is collected we'll update the value so now if we run level two you'll see gems is zero I'll collect a gem um move in the door gems still stays at one because when level one was loaded already was called and it went and said oh okay let's set that HUD value accordingly and uh that uh yeah that does that so we've got our HUD that's a duplicated duplicated and we want to make that better because right now you know every time we add a level we'll have to go and update this to say level three or update the label accordingly and uh let's go ahead and make that better so go to HUD right click save branches scene and we'll just call it HUD dot tscn save this and now here you can see HUD dot current level is two and gems label is zero and you can keep it there just like that to have it be like a mock-up but we're going to then set the value with code accordingly and we're even going to find functions on our HUD that let us set it externally more easily so we'll create HUD dot gd and we're not going to do anything too fancy here and we'll just instead we'll say a lot of function called level and we'll just say number because that'll be the level and we'll say HUD dot current level we'll actually copy the code from level dot gd because I think that's quite nice oh we don't have that code yet sorry so we'll say HUD dot current oh we don't even need to do HUD we can just say current level dot text is equal to a string of level colon and then space and remember num is going to be a number so you just convert it to a string great and then we can say funk gems and we'll count them right and we'll say current level instead of current level we'll say gems label dot text is equal to gems colon and then we can even just keep them both called number those parameters and then in our level code here we'll say instead of printing here on ready we'll just say um HUD and we'll call that new function which was level and we'll just pass in level num great so that's that's that there and then in set gems label instead of saying HUD gems label text all we need to do there is say HUD dot gems and pass in the number of global gems collected you could instead of passing in the number just get it from global but we don't necessarily know we'd always use global and I think it's better to have you know our little scenes that we compose our game with try to be as um encapsulated as possible and receive the data through parameters rather than um accessing global resources but you know just know could have done it that way too if we wanted so let's go ahead and run this test it see if it works because we just changed a bunch of things so level two worked gems are zero and if we okay we've got an issue here so we loaded level one and we called HUD and it says non-existent function level in camp in base canvas layer that's because in our level one we're using our old HUD so we can actually delete this note that's not the HUD that we created as a scene that was the old HUD so now we can click the chain click down to HUD and add a HUD I'll just drag it up here just to make it easier to see now this is our shared HUD right you can see that because of the movie clapper and it has our shared script so um level gd will work automatically for any level we create now right and I know that seemed like we just took a bunch of steps pretty quickly but what we did was we made it so that each level has one shared script and that shared script makes it a lot easier to add level three in the future and just makes it um yeah we'll just make everything feel a lot better and now you can see level two and it's keeping track of our gems we can switch between our levels that was a really big step we just took in all those waves so let's go back to the to-do list congratulate herself because that was great um and I was thinking about some yeah I've got ideas for like what you can do when we're done but oh and instead of fleeting that let me put it down here at the bottom so let's go ahead and add some sound effects and we can add a music track we can also let's make it so we can reset the level really quick actually because when we die that doesn't feel so good connect door player signal entered oh yeah that's that's maybe something you could do right how would you make it so that you could connect your doors with code signals rather than um connecting them manually right just like we did with gems so that's something you could do you could make play your movement feel better with acceleration and drag that would be good research to learn on your own um yeah we'll add a full screen setting just for fun and um we're getting really close we're getting really really close to the end so let's keep going level reset okay so let's make it so that in our level code right we have our level script if we jump off the end ledge we don't have to quit to restart let's go ahead and add a quick input map for that and uh have that work accordingly so we'll add a new action called reset level and click add and i'm going to map it to the r key and i'm also going to map it to triangle on that sony playstation controller y on xbox and just hit okay great then in our level code we can say funk input if event is action press and now we've got reset level as an option so we can call get tree that gets the tree and you can say um reload current scene and you can have it call that right away but it's generally best practice to say call deferred and that's much like q3 happens when the game and the game loops idle you can call deferred there that way if there's any data that's saving or being accessed it doesn't create any issues so now if we run our scene and jump off the ledge if we press r our player responds right there and maybe you could build a game around like making it really easy to reset your your game and when we reset our gems doesn't get reset so um if you wanted to do that you would just say global dot gems collected is zero and you'd also want to set gems label and then how could you write a function that um does both of these things in one one call that would be a good extra credit too but let's go ahead and collect a gem and then we'll miss our jump now if we press r it resets a good bonus extra credit too would be make player reset when they fall out of the level bounds that's a little bit more advanced but it would be something I think you could figure out given the things we know with area 2d and stuff so let's move that down here let's add a sound effect for when the player jumps so I like to use a tool called jfs js fxr javascript sound effectser which is that sfxr.me it's a free sound effect generator and it's generally retro sound effects that um you can just click it and you can adjust the sliders too I like that one and you can just play it over you can mutate it changes it slightly okay and then you just click download it creates a dot wave file and then you can just take this dot wave file go to the dough make sure that you can see the resource area you can just drag it in now you have jump wave and you can double click it and play you can hear that great now we can go into our player scene add a child node and if you just type sound audio I mean not sound you got a bunch of options audio stream player 2d audio stream player 3d in audio stream player the 2d and 3d versions set different properties notably the volume based upon how close you are to the item emitting it so imagine you had like a boombox or a speaker in a game you would say you would use 3d or 2d depending on the type of game you're making and as your player gets gets closer it would sound louder for our case we don't need that so just do audio stream player regular and we'll rename this to be jump sfx and over here in the inspector you can do quick load jump dot wave and now it's loaded into the sound effect you can test it and play it you can change the volume in decibels so like if it was too loud you can make it negative two decibels and here see where we say if it was just press jump and you're not on the floor set the velocity to the jump velocity now all we'll do is we'll just say jump sfx dot play and that's a function so you put the parentheses now if we run level one and jump oops i started the full game and jump we have a little sound effect great how could we make it so that we have a sound effect for the gem well there's a one that might be called like pick up corn i like that one so click it save it i'm just gonna call it gem i just renamed it quick drag it in we'll do the same thing right that's what this is all about it's just practicing so here we have on body entered player gem collected gem collected admit and then we can say we'll add a new audio stream player to our gem to the you know the gem root scene we'll go ahead and quick load and we'll call it gem we'll call it collected sfx and we'll say collected sfx dot play we'll run our level two just to test that one i've heard the sound effect play for the gem why would that be right let's talk through that so we cue free so the first moment can we say cue free the gem but then we can't play the sound effect see there are a couple of options here we could remove the sound effect when it's done playing sorry we could remove the gem when it's done playing that's one option you could make it so that the gem collected sound effect gets emitted which we already have and then someone else handles playing sound effect accordingly we're going to the first one because i think that shows us will show us a couple new concepts so click into collected sfx and say connect finished and we'll connect it to the gem script so on collected sfx finished then we'll cue free so we won't cue free until the sound effect is done playing now if we rerun the level we should hear that sound effect did you hear that but you might have noticed that the gem is still visible even after the sound even after we collect it let's fix that all you have to do is call hide it's a function that exists and it hides itself so instead of deleting essentially deleting removing the gem from the game we hide it we play the sound effect and then when the sound effect is finished we use that signal to say okay call cue free which then removes the gem so if we go ahead and rerun our game now we've got a sound effect for the player we've got a sound effect for the gem oh yeah this also reminded me of let's um as part of cleaning things up let's go and um we'll add level three at the end because that will be fun the quit option we'll just yeah we'll add that that's easy um and then we'll um I want to make it so that um switching to levels with a nicer interface okay sorry about that I just um remembered that so we've got sfx jump and gem done right that wasn't too bad I really like this tool it doesn't make you know super modern sound effects they're very retro but I think that can work really well music track okay so music is always interesting because um yeah it takes time to make but we'll go ahead and we'll just go to open game art and find one that we can use so here's one by wolfgang it's an 8-bit game and it has a license of creative commons to give attribution so uh you know you would say this is by ted kerr and uh yeah we can go ahead and add that into our game so um all you do is from open game art or wherever you find your music is uh we'll use the dot org so dot org is like um it's an open source audio container format and it's much smaller than dot wave so here you know the dot wave is 6.6 megabytes and the dot org is 2.1 so it's three times smaller and compared to mb3 mb3 has some proprietary licensing so dot org is preferred and godotplays.org so you just drag it in and it imports it you can double click it and play it that's nice so then in our level we've got some options we can have a different level like a different theme per level if we wanted to do that we would have to go and find a second audio track let's actually see if wolfgang has another one here's a quirky waltz that's really fun it's only in dot wave so we'll just have to use what we've got you could convert it maybe uh hmm this one has an mp3 but um oh that's kind of fun uh okay anyway we'll give we'll make sure we give wolfgang credit accordingly too in our game but annoying waltz is uh it's a bigger file you know that affects how fast your game loads but um nonetheless we'll use it you can say whether or not you want the it to loop so we'll get into that in a second um let's see so okay sorry let's go to action theme i'm getting a little bit ahead of myself click in action theme and click import and we want to loop it because it's music then click re-import now it will loop we're going to do the same here i'd like to do the same but maybe we can't uh oh yeah detect um forward now it should loop so okay we're gonna get into learning a couple new things here as we play our sound effect so we're gonna add another audio stream player to our level and we'll call it music here in our stream we'll quick load and we'll go ahead and we'll quick load um action theme for level one and we already set it to loop we're gonna click auto play so that it plays automatically when it's added and we might need to adjust the volume but uh that will um yeah that will automatically play it and uh i think that we'll do the trick negative eight that's sounding pretty good but then level two doesn't play any music so all we do here is add audio stream player music and we set the stream quick load we'll make it annoying waltz now if we go ahead and run level two hmm it's not playing and i don't know why oh because we didn't do auto play so you gotta remember to do auto play it's a little bit hard and then we go to level one and on next switches so now we have two levels with different music that auto plays cool that was actually really easy let's make sure we give ted ker credit so i'm gonna copy their name and then in our main menu we'll go to 2d we'll add a label and we'll just say music by ted ker and we'll also say sprites by kenny even though the kenny assets are public domain i really like to give credit um even if even if credit is optional it's really good to be in the habit of giving credit to people um i really think it's super generous that people make these free assets to use in games so we've got sprites by kenny music by ted ker we're uh it's not a game right like isn't that cool when we press r we set the music which is cool just like our level so you could go and um yeah we got music let's figure out our next step so we want to focus on the main menu buttons when we launch the game for controller support and keyboard support so right now the start button only hovers and is interactable when we hover over it with our mouse cursor but there's a way to make it focus automatically and then it becomes controllable with our keyboard and gamepad so i've got my ps4 controller that i just want to use to test it out and what we can say here is in our main menu script on ready we can grab the start button there's a focus there's a grab focus function and that says when our game is ready grab focus of this and you can now see there's a white outline around the start button and if you press the enter key it goes ahead and triggers it and when we press escape it's focused again but you'll notice that the gamepad doesn't work so this is where we go into input map and we show built-in actions and see ui accept we're gonna want to go ahead and make it so that that works with our other keyboard mapping so i'm gonna make j i'm gonna make the z and then i'm gonna make the x button on the ps4 controller sony cross work now if we run the game i should be able to press the x key in our game starts and i can go back to the main menu and it's focused so that is there great that was easy now let's make it so that we can toggle full screen on a button press this will be pretty simple and you can make it more advanced and you could even have it save to a user setting i have a project called godot skeleton that's a starter kit for your games that handles this kind of stuff so you could check that source out if you want to see how that's done for our case we're just going to go ahead and add a real simple one so in the main menu just duplicate start button and say we'll call it full screen button and we'll drag it down whoops just drag it down i'm holding alt and we'll just call it toggle full screen great now if we run our game we can't move up and down to toggle full screen with the keyboard and the controller but there's a way to make that happen the way we would do that is we can actually add a child node called the flow container that's vertical flow container we create that drag these select them drag them within it and just call it options for menu options and then we can go ahead and make it so that if we make this taller however tall we want to be and then however wide we want to be the options within it automatically stack and that's useful in and of itself but because they're connected via the v flow container we can use our keyboard and game controller to move between the items but now we have an issue and you can see that start button was has changed its location so we just need to update our code there now if we press down or up on our controller it goes and grabs focus of the next one and i did toggle full screen and it started the game that's because our full screen button has pressed connected to on start button pressed so disconnect that connect this here we'll just connect it in main menu on full screen button pressed godot has an option called a class called display server you can do window set mode and there are a bunch of different window modes that exist exclusive full screen full screen maximized minimize windowed and what we want to say is full screen now if we save that run our game again and press that button it went and made the game full screen you might notice a couple of issues one now the game's only in the upper left corner and if we press it again it doesn't toggle it back so we can do a couple things there might be a way to say display server dot get window get mode and that gets the mode of the window and we can do print the bug to see what that is just out of curiosity it's probably an enum yep so it's zero and then if we toggle full screen toggle it again quit our game it's set to three so we can do this we can say if window dot get mode equals equals display mode let me expand the code since we're coding so much then we'll set the mode to display server dot window mode window and I forgot my colon at the end here l if the display mode server is window mode windowed then we'll set it to full screen and I think full screen is preferable to exclusive full screen because exclusive full screen can like I think it affects the resolution in a way that might be undesirable for your like host operating system so now if we go and toggle full screen we can toggle it back and forth and that's pretty nice you know it'll always launch windowed but if you want to change how your game launches you would just do this in our global ready but I don't want to do that so we'll leave it but um so that's that now we have full screen toggling but we notice that it scales funny and if you take your window here and scale it it's kind of weird right the level gets cut off that's not what we want we want the games actually get smaller with it so we can go to project project settings and in general there's just a ton of different project settings that you have you can set your game icon which that would be kind of fun to do we'll do that at the end let's make a little to do but what we want to do is go to display window and this is also a place where you can change how it launches too so you could do it in your settings or you could do it in your code but we're going to leave it as is but we want to go into a stretch and then in stretch mode it's disabled I think we want to do stretch viewport and keep the aspect ratio so now if we run our game and we change that see how it scales and we get the black bars the letterboxing that's preferable for this type of game because now if we make it bigger or smaller the game reacts accordingly now for some reason our toggle full screen button doesn't work anymore so let's try to figure that out maybe it was just being funny while we were changing that so now we can toggle full screen we scale the window size accordingly you might notice text gets a little blurry when you scale it I truthfully don't know how to fix that at this point there might be different ways to do it I'd have to do some learning but it does text does appear to get a bit blurry and pixelated if you used a pixel font and you scaled your game like this with that viewport setting that would look pretty nice so I just want to see something really quick if we did it mode canvas items let's just see what that does because I don't even know oh everything looks a lot a lot smoother with the uh with the text so I think we're living and learning that's awesome let's figure out what that does so kado mode canvas items let's see what that does okay so kado has some recommendations for non pixel art use the stretch mode canvas items we're using pixel art for pixel art change the stretch mode to viewport let's link to this in the description um I think that's quite helpful so I'm going to leave it as canvas items because I think it makes the text look a lot bigger or look a lot better but you know change it as needed so we've got our full screen setting let's put that in done now our next one is we want to have the ability to quit the game and also we only want to show that on the web on desktop because in web builds you can't quit it you know you would just close your tab and also full screen toggle on web is a little different itch.io where we'll host the game we'll handle that for us so we're going to hide that on uh web browsers too uh our full screen toggle so let's go to our 2d view and here in our options button we'll just add another button we'll call it quit button we'll give it the text quit and in our node we'll say pressed on a quit button pressed and you can actually just do get tree you can call the quit function so now when we launch our game we can navigate down and quit the game that's kind of nice I also missed a couple of input maps so let me just go ahead and um you might need to add it for UI left right up and down because I want to support WASD I'm just going to map these really quick because these are the built-in UI actions and UI up I just noticed because I pressed WASD to go now I hit the menu and it didn't work so now we can quit great but let's make it so that our quit button and our um full screen button are hidden if we're not if we're not on the desktop computer so Godot has this handy check we can say if and are ready for main menu if os has feature and there's a feature called pc now if we run that pc gets output so we know that we're on a pc and we can click into here has feature and we can refer to the feature tags document to see what exists so you can check if it's debug you can check if it's desktop or mobile or web and what we checked there was pc so if it's a pc platform desktop or laptop if it was web or mobile it would return false and if you're on a mobile device you usually can't toggle full screen and if you're on the web you usually can't toggle full screen so we'll say if it does not have the feature pc then we will say full screen button hide so and we'll also do quit button that hide so now those will both be hidden only on web and pc build or web and mobile build so anything that's not desktop pc and we'll see that when we upload the game to itch but for now just know that that's there okay great we've got the quit option let's set the game icon let's make up level three and then we'll um export our game and upload it and then let's go extra credit this will be advice for where to go from here so okay let's do set the game icon so in our downloads you can see there's a folder of just tiles and let's pick one from default that we think represents our game and i'm probably going to pick one of the players because i think that's fun so here's one with oh but i don't remember which which player we use let's play the game and see okay so it's the one with the curled horns see how these players these uh characters have different horns oh my gosh it's really hard to find things okay here we go we'll make this our icon so i've just copied that oh no i'm gonna click it drag it into our game and now you'll see tile two four one i'm going to rename it to be icon dot png and then i'm going to quit or i'm going to delete icon svg also i'm going to stop running the game a nice thing that you can do as you're working on a game especially if you add music is add a setting to turn music on and off uh good dose skeleton which i mentioned also has that which can be really handy while you're developing so now you go to project project settings go to general and go to application config and for the icon just go ahead and select icon dot png close it now if we run our game you'll see that the icon is our little icon there and you may have noticed that it's a little bit blurry and that is um because it's taking it and scaling it up so um i've got a couple options there we can do open an external program wow didn't like that we can do show and file manager and we could open it and i'm going to open a sprite which is a pixel art editing tool i'm going to just do file export and i'm going to export it at a thousand times it's normal size i'm going to export it at 10 000 times it's normal size actually and i'm going to save that here and overwrite it so now uh it's not bigger we could do this image right i'm going to make it 16 000 by 16 000 and save it got a little bit blurry in certain spots but it should be now it's uh quite a bit bigger i think that was an ace sprite issue delete this duplicated one and now we have icon png if we've re-import that run it again it should look a little bit better so now it looks a little bit better sometimes with pixel art you gotta like expand it for these icons to make it look good um so now we've got an icon and let's add a level three really quick and i think part of your job as the game developer and the level designer is to make the levels much better than i did so you know my levels aren't very good so you want to make your levels better let's take level two i'm going to duplicate it we'll just make it level three double-click it and make sure it's open and you know we have this door here and it says level one but maybe we want to make this say level two right and then remember how we changed which level we go to we just go ahead and change that there uh we've got these gems which we'll add we've got our player which is fine but let's go and edit the tile map so just like before we're looking at our tile map you select some tiles and then you can just draw them on there make them look good when you're in the tile map editor you can right click to delete whatever tiles there you can just paint like a paint brush there and yeah i'm not feeling very inspired right now to make a good level so um i'll leave that to you to do but let's duplicate these gems and just make sure everything works and we'll play test our level all right and let's rename this node level three just so it matches now we can run level three now we can go to level two but in level two let's make it so that we can go to level three so we'll just add another door here to level two go into level two go door door needs to be duplicated drag it here change the label and we'll make it go to level two save that it automatically updated so we can could have tested it um okay that seems like it's not going to the right place so let's go ahead and see what that is about let's just rerun the scene because maybe it has to do with um oh it's because i set it to level two but it needs to be level three also something that i'm noticing on level three sorry i'm a little all over the place is that our HUD is that we didn't change this number here to level three so now that it's changed to level three and if we run level three in the upper left we'll see the proper level so yeah i think that that's how you add levels you know pretty quickly you can just go drop in a level make sure you connect the doors or whatever it is you need to and change the data but um yeah yeah that's uh i think that covers that so we've got level three now these levels aren't very good but uh i think the pieces of the puzzle are there to do it so let's play test our game and then let's go and upload it to itch and we'll talk about exports so i'm just going to go ahead and i connected my controller press the play button and we'll give the game a test so i'll toggle full screen make sure that works okay let's start the game i'm gonna move my mouse you can hide the mouse cursor too if you wanted there's a option for that and then triangle resets the current level on my controller um or the r key does yeah that's feeling pretty good um and then let's do one little thing i noticed is in the main menu scene let's add a credit for for ourselves game by you so put your credit there and do that and now we've got a game that we can export and share on the web and uh with our friends or whomever players so what you want to do is go to project and go to export and we're going to configure exports for as many operating systems as we can this interface is a bit overwhelming at first but we'll get through it without issue so click add you'll see all the options you can export your game for it let's click web i'm just going to say it can't find export templates so click this manage export templates and you need to download the export templates for whatever version of godot you're using and it downloads nearly you know 750 megabytes of data this is the different templates for each operating system so you know for web for linux for windows for mac and or ios there's like basically a wrapper or shell that has godot compiled for those operating systems and it takes our game data in here and builds our game using them so while godot the program is pretty small we need this export data in order to share our game with people who don't have godot installed and it takes a little bit of time but not too bad and then it says okay they're installed and ready to be used you can close that then we go back to project back to export our web exports still there and now we need to go and click here in the export path and tell where we want it to export to i like to create a new folder called exports and then within there i'll create a new folder called a web and then within web name the file index.html this is what itch.io needs click save and then there's a bunch of other settings too and i'd say don't worry about those quite yet those things that we just did just where to export it naming it properly index.html and web that's all you need to do then depending on which operating system you're exporting your game on you can export for other operating systems a kind of funny thing is that on macOS you can export it for pretty much all the major operating systems whereas on windows and linux you can't export it for mac so there's some weird things there and then now you'll see for our macOS runnable path i'm going to put it in exports and i'm just going to call it 2d platformer mac.app and save that again there are other settings but if you're on macOS you have to set the bundle identifier so you can just do the like com dot your name dot um you know some kind of unique identifier that will do it for mac i'm gonna do it for linux and then here again sorry this window gets really unwieldy sometimes click into here instead of 2d platformer mac i'm just gonna call it 2d platformer dot linux dot x86 underscore 64 that's just like the godot's file extension for linux i'm going to leave these things here and you can embed the pck the pck is your packaged game files and if you just want like one file one executable that you can send to someone you can embed the pck and you can do that in linux you can do that in mac or you can not embed it up to you i'm going to click embed so that we just have one easy file to distribute and then windows desktop is the final one i'm going to embed the pck i'm going to set the export path to instead be 2d platformer windows and i'm going to make that a dot exe because that's the windows executable name and now we have all of our exports configured configured and you can export them one at a time by clicking export project and unchecking export with debug or now that we have them all configured you can click export all and do release because this is our release build and it will go and export your game for all of these platforms and there might be some warnings like there is for windows but it completed them and now you're like whoa my game is exported so you have to go into your game folder and find that exports folder and you'll see here's our game we have the mac version the windows version the linux version and the web version if you click index html it's not going to work because you have to properly um set up your web server for serving it but it'll work when we upload it to itch so let's just double check that the game works on our platform i'm on mac so let's just make sure that works okay yeah look i can just run this dot app file and i can toggle full screen i can run the game awesome that means i could go and send this to a friend and then what i'm going to do is i'm going to compress all of these into zips so that they are smaller and faster to download for people and it will upload faster to itch.io because out of the box godot games are pretty hefty in size like if i look at the linux build it's 76.8 megabytes the mac the mac build is 145 megabytes it's pretty big but if i look at the mac app now compressed it's almost two-thirds smaller which is you know pretty considerable so um that is a downside to godot web builds or godot builds is that they are quite a bit bigger especially in godot 4 so you go into the web folder and don't compress the top level folder web compress all the files within it and then i like to rename it 2d platform web and i'm gonna move this up to my exports folder so now when i go here if i organize these by name let's actually organize them by kind we can see all these zips here these four zips we have linux mac web and windows we're ready to upload them to itch so what you do is you go to itch.io let me close some of these i'm gonna save this feature tags to put in the video description and you go to itch you can create an account if you don't have one already itch is a website for sharing games and you go to your dashboard and then way at the bottom you can do create new project and i'm going to name this godot 2d platformer it will automatically create the url you can add a description which is great and then for kind of project you're going to select html because we have an html build if you made a game you didn't have an html build you would just say downloadable that your players are going to download it and then make it whatever you want it to be when you're working on it right now it's a draft so no one will see this for me i'm going to make it prototype because this is just for learning and teaching then you can click upload files you go take these files select them and then godot is going to go ahead and upload all of those in parallel and anytime you want to release a new build you would export all compress them and you can actually configure your exports to go to zip right away but i noticed a couple of weird issues with that so i usually do it myself and then you go and upload it and godot would or itch would know to do that now there are a couple other options here the godot skeleton project i made has a script to automatically handle creating the export and uploading them there's also an add-on for godot for uploading to itch i haven't used it myself but it seems pretty nice and so this is the most like bare bones slightly cumbersome process but i wanted to show you it because this is you know you can automate it make it better then you go in and you select the platform for each one linux this little penguin mac is the apple web is um you just leave it as is but you say this file will be played in the browser and then itch knows to load that and then you have your windows here we can go ahead and set our size of our game in godot in our project settings down in window there was a default size for our game and uh so i like to mirror that on itch and then if you wanted your game to launch smaller you could just change it here but remember our game will scale so you could make this a different size but let's just stick with that for now and we can add a full screen button to make sure that the game could be made full screen add a description i'm gonna add a genre of platformer and i'm gonna add a tag of godot and um so you'll see it's draft so if i see even view page it brings us here and it says loading game for the first time and i can click run game and you'll see there are a couple of issues so we actually have to go back to edit game and you have to for godot 4 click share buffer support experimentally you have to enable that that's what allows our game to run in browsers i'm gonna zoom out a little because my computer's resolution is really small now this final step takes a long time on mac operating systems on windows or linux the game would have already loaded and also know that with godot 4.0 safari web builds like web builds don't work in safari it's just an issue with safari that is out of godot's control but if you were on windows or files on windows or linux this would be faster and that's nice but while that's running you can now see someone could download your game and they have access to the different files based on their operating system i'll even show you in the godot desktop or the itch desktop app where you can go ahead and download and play a game too i'll just do that while it loads because it does take quite a while so itch has a cool desktop app for games that you can just install easily within the sandbox of the itch app so let's go down and find my platformer game it might be at the top let's see platformer godot 2d platformer and then i can click install and it says not found because it's a private page but it's automatically finds the mac app and will start to install it i can launch it and it launches our game so you know a friend or whomever could find this and play it hmm it seems like the music's playing twice well that's odd but uh now you'll see that we're our web version launched and we don't have our icons we don't have our buttons for quit in fullscreen because we're on the web and fullscreen works differently we can click start and our game plays and works in the web and you know you could share this game with your friends keep working on it that is a godot 2d platformer from scratch i hope that was fun i hope it was helpful there's a lot of different moving pieces to making games and i thought it would be helpful to show from start to finish how to do that so now that we've got this done let's talk about some things you could do from here so you could you could instead no i don't even know what that is let's just get rid of that one i forget the context there so one thing that i've noticed is that the player movement feels pretty bad um the way the player controls just feels real um real slimy to me and and you would want to make your player movement feel better there are a lot of options here and i think part of learning game development is independently researching and figuring this stuff out um i have a project on github called godot types where i have smoother platformer movement i would recommend looking at that if you need some guidance but right now the way that this moves is it once you press a button we just immediately apply the full speed so your player goes from zero to full speed real quick your playable character you would want to add some acceleration and deceleration and some drag that would make the platforming feel a lot better you could do variable jump height like mario where when you hold the button you jump higher but then there's a ceiling to how high you can jump that would be pretty interesting um you could make it so that the player is position is reset when they fall out of the level bounds or they die um and then like add levels add and design levels um play games for research you know celeste and super meat boy come to mind you could add enemies and adding enemies is a bit more complicated but you know you've got this foundation and i think you could then expand upon it from there if you'd like to see some if you'd like to see a follow-up of part two i'd be interested in yeah we could do something with enemies and sure that's potentially interesting but i think what i would follow this up with is making a 2d action shooter like contra or like caro blaster if you've played that or heard of that or mega man because a lot of this 2d platformer foundations if we just give the player a blaster and enemies to shoot like we can make a whole new you know type of game so that's 2d platformer with gado from scratch from nothing to shipped game using public domain assets or creative commons assets with levels that we can build and design thank you so much for watching and following along let me know if you have any questions and see you next time