Godot 4: Build Online Multiplayer Pong Clone

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys in this tutorial we'll be making a multiplayer pong game let's start by creating the UI for which our players can connect to our game so I'm going to create a 2d scene I'm going to name this network manager I'm going to add a child node of control I'm going to add a panel node I'll spell that right to our child and I'm going to center it and make it big and nice like so I'm now going to add a vbox container so that everything will align vertically and I'm going to just stretch it to about the size of our panel going to add a child node hbox container which will align things horizontally and I'm going to align it I'm going to align it at the center I'm also going to align the vbox container container at the center as well going to add a child node to this and I'm going to just add a label and I'm going to just call my label multiplayer PP and so I'm just going to change my hbox container to say title my label I'm going to just go to theme overrides font sizes and I'm just going to increase the font to something that looks more like a title so much bigger text just like that I'm now going to duplicate my title and I'm going to call this IP and I'm going to make my label say IP label so we need to get the player's IP so that you can connect to the game so I'm going to change our label text to just say IP address and I'm going to shrink the font size so that it's less annoying I'm going to add another child node to this hbox container and I'm going to just give it a text edit going to rename this to IP text now I'm going to set our textbox default text to be 127.0.0.1 so this is an IP address and it's what you'll use to connect to a server this is every computer's local IP address so this is essentially just something so you can connect to yourself this will not work for other users over the Internet for that you'll have to port forward and I'll have some links to resources on how to do that in the description now we can go and change our layout so that you know it's not so small so I'm going to increase our minimum X size to not 500 but 200 maybe and I'm going to increase our y to 30 that looks good I'm going to duplicate this again and now I'm going to delete the label and text and I'm going to rename this um buttons going to add a child node and it's just I'm just going to get a button and I'm going to have this button's text say connect and so I'm going to name this connect button and I'm going to duplicate this name this host button and change the text to say host not connect host but host there we go perfect so when you click these buttons it'll essentially connect will just connect to a server host will host the server on your computer and allow users to connect to it now let's program players being able to connect to our game shall we let's go up to our netor network manager seen and attach a script I'm going to keep this network manager and I'm going to make it C I'm going to get rid of any defaults for it since we won't be using a lot of those and create so now I'm going to have to define a couple variables so first variable is going to be the port so constant Port equals something like 2556 which I think is Minecraft's default Port so the port is essentially a whole through your firewall which you'll have to create if you want other people to connect to you over the Internet so the next variable is going to be a text edit so export text edits and I'm going to call this IP text and the final variable for now we'll Define more later is export control and I'm just going to call this UI so now if we go back into our gdau and build the scene and save our scene I guess I'm going to call this y network manager now we can assign our IP text so our text edit here and we can assign our control to the UI perfect now let's connect our buttons to the script so that our people can actually join and host servers so I'm going to go here to the host button and go into node and going to click the Press signal and connect it to our network manager script I'm going to copy this and click connect so back in our script I'm going to create a private void and I'm going to paste in that string I copied earlier now let's Define a variable enet multiplayer Pier I'm just going to call this pier equals new enet multiplayer Pier and so this is essentially the variable we'll be using to create our server and we'll have to Define this in our connect button to create our client as well and so now we can just do pier. creat server and hand in our Port that we defined up here now we could do some error checking to make sure the pier actually connected so if Pier do get connected status equals equals multiplayer Pier connection status. disconnected what are we going to do I'm just going to GD do print and say server creation failed and then I don't want to run this code anymore so I'm just going to hit return so if our server creation is successful now we need to set our multiplayer Pier multiplayer Pier multiplayer Pier equals our current Pier that we created this is essentially passing our Pier off to for the GDOT to handle all right now let's do this again for the connection button so we can go back into our game and click connection button and connect the signal to our script again so I'm going to copy our variable or our function name and click connect and create another private void paste our function name in now we're going to have to do a bunch of these steps again so enet multiplayer Pier Pier equals new enet multiplayer Pier pier. create client this time this time we'll be passing in the IP address we took in from our UI so I'm going to do IP P text. text and then passing a report I'm going to copy our error detection here paste it and just instead of server creation failed client connection failed for error message once again hand this off to gdau to handle multiplayer do multiplayer Pier equals Pier now let's create a function for our both our client and our server to call once they've connected and hosted the game so I'm going to do another private void start game and I'm going to pass in a parameter of a long and ID so this will be used for Authority later which I'll explain and all we're going to do with this right now is do ui. hiide do hiide so now on our server we can call start game and we can pass in multiplayer. getet unique ID to it and so what the unique ID is is it's a random value given to our players once they connect to the server however if you are the server on the server this unique ID will always be one this is the way I this is a way of identifying which players are which in a very simple way so that we players aren't controlling each other's characters so I'm going to copy this and paste it onto the client side as well finally we're going to want to replicate our start game function on the server when the client connects because if the client connects and start spawning things essentially it's going to be security risk and and someone's going to ruin everyone's game so we can go up to our server and do pier. peer connected so when a pier connects Run start game perfect so now if we go into gdau and run our game and I'm going to select our current scene as the main scene and I forgot something if we could go into debug and we can run multiple in instances so for this game since pong has two players I'm going to run two instances so now if we run our game it'll pop up two windows so on this window I'm going to click host and our UI will disappear in this window I'll click connect so you see no errors are popping up in our error log so perfect you've now created a basic multiplayer server for users to connect to now let's create a player for people to control so I'm going to close these and create a new scene and I'm going to get create click other note and give it a character body 2D and I'm just going to rename this to player I'm going to add a child Noe and I'm going to give it a Sprite 2D and I'm going to pass in the default gdo icon for this since I don't really have other graphics on hand and I'm going to make it look like a pong paddle so I'm just going to decrease the size here now I'm gonna add a child not and give it a collision shape 2D going to give it a rectangle shape and drag it to about the parameters that look about accurate for our pong paddle I'm going to save our scene and I'm going to call it player now this next step is very important we need to add another child scene and I need to add a multiplayer synchronizer this is how the server will tell things like position so if I can go down here into our replication and add a property to sync and I'm going to click our root node player now I can look up position so this will sync the position across the network so I'm going to save our scene again and now let's spawn our player so back into our network manager and back into our network manager script in our start game UI or actually here I'm going to Define one more variable export hacked scene and I'm just going to call this player scene so save this go back into gdau and build now I get to drag our play player scene directly into our network manager now back into our script here in start game Let's spawn our player let's instantiate our player character body 2D temp player equals player scene. instantiate and I'm going to say instantiate as a character body Tod now this next step is very important so if you remember up here where I said calling a unique giving a unique ID is going to tell server which player is which well here is where we're going to give it that data so I'm going to say temp player. name equals id. twring so ID is what we passed in right here and we'll use this later to give Authority which is essentially is saying again who owns what now I'm going to want to spawn our player into the center of the screen so I'm going to just do temp player. position equals get viewport do get invisible rect do size divided by two so this will spawn it right in the center of the screen now since our network manager is our root node in the scene we can just do ad child temp player perfect so if we go back into our network manager scene and since we're done with control I'm going to minimize this here we need to add one more thing to our network manager to actually allow us to spawn our player so I'm going to add a child node and right here we can add a child node of a multiplayer spawner so we now need to select our spawn path which is going to be the root node of our scene so the network manager and now we're going to create an autop spawn list so I'm going to add an element here and I'm just going to drag in our player that we created and I'm going to save this so now if we run our game again and I'm going to host and you'll see it created our first player and I'm going to connect over here I think the players are just on top of each other so this this is our way of synchronizing creation of players so I'm going to close this now and let's give our player some logic let's give it some movement logic so in our player script scene I'm going to add script and I'm going to call it player. Cs and I'm going to inherit nothing again so first thing we're going to do is set our Authority so we're going to tell our player who owns this object so we can do public override void enter tree so when our player enters the scene enter tree I'm going to keep this base tree just in case we're going to set multiplayer Authority we can just do in 32 dot name oh in 32. parse and pass in our name so this will set our Authority now let's add some startup logic so public override void _ ready it always does that ready there we go going to just delete this so now we're going to check if it has multiplayer Authority so if not is multiplayer Authority return so if you do not own this object you cannot run anything in the ready function now since we only have two players I'm going to check if it's the server so if multiplayer dois server what are we going to do well we're going to set our position to each side of the screen for the server and the clients so position equals new Vector 2 and I'm going to set this 50 units away from the side of the screen and get viewport do get inv visible rect size doy / two and I forgot our brackets here so now I'm going to do an else so if we're the client position equals new Vector 2 we're going to keep it in the center of the screen but now I'm going to copy this paste it here make this the viewport size. x minus 50 so now it'll be equal distance away from each side of the screen so now if we go back into gdau and run our game again and we host it'll appear on one and we connect and there it'll appear on both sides of the screen so now let's go and add some movement to our players back into our script let's create a public override process so run on every frame we don't need the base process so once again if not is multiplayer Authority return if you do not own the object this is very important if you do not own the object you cannot control it now let's add some basic logic if input. is action pressed I'm going to say UI up so I'm just using the default controls for now and I'm going to create create a vector 2 I forgot to do that Vector 2 V equals Vector 2.0 and it added system. numeric so I'm going to delete that reference v.y equals 1 so up on the Y AIS Times by a speed variable which we'll create and might as well do that here so I'm going to do export speed equals float speed equals 200f perfect now we could do else if input. is action press UI down v.y equals 1 Time by speed so go down on the y- AIS now we're going to just set our velocity equals Val and call move ins slide so it actually moves every frame perfect so you might be wondering why this code looks so similar basically to a basic controller like realistically the only check we do is if multiplayer is is the owner of of the object the reason we do that is because of this multiplayer play synchronizer we did here it's going to handle all the calculations for a position which is very nice that gdau does that for us it saves a lot of work so we can run our game again and I'm going to just put it on both sides host connect perfect and you can see now I can move up and down and you're going to be able to see it on on each screen so this is working perfectly but this isn't really a game yet and we want to add a ball so let's create a ball for our pong game so let's create a new scene I'm going to make this a rigid body 2D I'm going to add a child and I'm going to make add a Sprite 2D to it and once again pass in our default text our default texture that gdau gives us and I'm going to change our transform and let's set our scale to like three uh 0.1 let's make our ball small and add our Collision shape 2D and another rectangle it's bit too big for us so let's just yeah that looks good let's save it as I'm going to actually just name it up here as ball and let's save our scene as ball. tscn perfect so now I don't want our ball to slow down or drop when it spawns into the scene so I'm going to set its gravity scale to zero and I'm going to set its linear damp mode to replace so no damp while it moves no damping so it won't slow down through the scene now if you're a member on our player we have this multiplayer synchronizer and we're going to have to do this again so add child node multiplayer syn not spawner multiplayer synchronizer and add a property to sync we're going to add the ball and once again just the position we'll do save our scene now let's add our some logic to our network manager to spawn the ball so let's go back into our network manager script and I'm going to create a new function or the process function public override process and I'm just going to create a little private bu has ball spawned equals fall or equals balse yeah that'll work so now we're only going to want to spawn this ball all if we're the server so in the process we're going to check every frame if multiplayer. iserver if we aren't the server so that's what this exclamation point here is if we're not the server what are we going to do we're going to return we don't want the client spawning anything on the server so now we need to check if both clients are connected we're going to start the game so if multiplayer. getet Pierce so so how many people are connected to the server length is equal to or greater than equal to 1 so be aware computers count from zero so this means two and has ball not spawned so if if this is true it's if has ball spawned is true we're not going to run this so we're not going to spawn a million balls in the center of the screen so I forgot to get reference to our ball so export pack scene ball scene and let's go into G build again and we'll just drag our ball scene into here perfect save our scene back into the script so this is going to look very familiar to when we spawned our player rigid body 2D new ball equals ball scene. instantiate and it's going to just be a rigid body 2D again now let's set our new ball into the center of the screen so new ball position equals and I'm just going to go down here copy this get Viewpoint get visible re size divided by two and paste into here we want it to spawn right in the center of the screen and once again we can just add Child new ball so this should work so once both players are connected we're going to instantiate our new ball put in the center of the screen and then add it to the server again so you might be thinking that there's probably a better way to do this and you're probably right but like this is not the most efficient way but it's a way that works so we're going to go back into our scene and run our game again so I'm going to click host and connect I forgot to do a few things here first off I forgot to add it to our multiplayer spawner so it's not appearing on our client and I forgot to set it um has ball spawn to True when we spawned our ball so let's go do that right now multiplayer spawner add element add our ball scene save that go here and has ball spawned equals true let's run that again and this time it should work host connect there we go the ball spawn but it's not doing anything because we haven't programmed any logic to the ball yet so let's do that right now let's go to our ball attach a script ball. CS will work I'm going to keep it empty and create now this is going to be a very simple script public override void uncore ready it always removes the R I don't know why if the it's not the server so when we spawned our ball return so when we spawned our ball over here if you noticed we didn't assign any Authority if you don't assign any authority authority just automatically goes to the server so the server has control over anything that isn't assigned automatically so if it it's not the server return we don't want this logic being able to run on the client now we're going to set our linear velocity linear velocity equals new Vector 2 let's just set it to 1 one times by speed or let's just do 200 okay so after some testing linear velocity is not the best way to do this so I'm going to do set axis velocity to the new Vector 2 one one times by -200 that should be good now let's test our game because I was getting some errors before host connect there so if you notice I'm glitching there it's because the replication isn't perfect and essentially we need to interpolate to make movement feel perfect on the server so I think that's fine for now so now let's actually make our ball be able to bounce off things so in our ball scene let's add a physics material let's go into it make our friction zero and our bounce uh one so it'll have equal bounce maybe we can make it two to make it double the speed every time it bounces off something um now we can go into our network manager and we can add things like walls around our scene for it to bounce off of so that it doesn't just fly off into Oblivion so let's add CH load I'm going to add a static body 2D I'm going to add a collision shape 2D and another rectangle that looks good so I'm just going to drag this across the scene and I'm going to duplicate it and drag this down to the bottom now our ball shouldn't jump off the screen okay let's add a scoring system so I'm going to add in a new control here and we're going to call this scoreboard and I'm going to add a child node and I'm going to give it a label and let's put the label somewhere like here and let's just give our label the text of zero good default text and let's do our theme overrides fonts and let's increase it font size and let's increase it so that it looks pretty good so font size of 50 perfect duplicate our label drag it over here to the other player side of the screen I'm going to do player one score label and player two score label label perfect so let's add some colliders on both sides of the screen so that when our ball collides with it it'll give points over to whichever player you know owns has that side of the screen so I'm going to add a child node I'm going to add an area 2D and I'm going to add another child node Collision shape 2D let's give it a rectangle shape again we're going to use a ton of rectangles and let's just drag it to its side of the screen we're going to call this player one score collider perfect and duplicate that just player two score collider now for player two we're just going to drag this to the other side of the screen not do that going to zoom in and drag perfect save it and we need to add a script to our collider so attach a script and I'm just going to call this scorekeeper because we're going to be reusing the script on both and I'm going to grab export um label scoreboard uh how do I spell board I don't know so we're going to be able to drag that in and let's connect a signal to it signal to our script so body entered body 2D let's connect that to our script and copy the body entered code so now we can add it in private void paste that in node 2D and I'm just going to call it node so if node. name equals equals ball which I believe is what we called our ball let's just double check it in gdo yeah ball with capital B perfect so if it's the ball what are we going to do well we're going to have to update our scoreboard so I'm just going to add an INT score counter equals z and we're going to increment this by one so score counter Plus+ let's change our scoreboard so scoreboard. text equals score counter do two string and let's run our project you might notice an issue here so let's host connect let's let the ball go off screen let's actually assign the score board that we need to let's run that again host connect so tell me the issue here see it only runs on one so we don't have a multiplayer synchronizer for this and for when we don't have that we need to do rpcs rpcs is essentially sending a direct message to the server to say communicate with the client so we can create another function here private void or actually yeah private void update score and we're going to pass in int score int uh new score let's give it a different name and so now here we can do scoreboard. text equals score counter. two string uh new score. two string but how is this going to run on all the clients well there's this handy little thing called an RPC which is essentially saying send a message to all the clients from the server and so we're going to want to make sure it gets to all the peers so we're going to do multiplayer api. RPC mode do anyer so essentially this is saying give it any Pier will send it to any client on the server disabled will send it to no one so we'll do any Pier for this so now to call the function we can't just call it like any other function so like we can't just do update score and then pass in our score counter we actually have to do something a bit different we you need to use the RPC function to call our V our function so RPC update score and now comma score counter so now let's go and run our game and now the score should be replicated on both the client and the server see now it works so now we need to do that again for the other side so here we can just drag and drop our script attach our body entered connect do not need to change anything in there and set just refresh this our scoreboard to player two score so now if we run our Game host connect let's oop so now if it goes onto this side of the screen let's Dodge it here it'll set so if you notice it'll set the score to one so if you notice the ball doesn't spawn again so let's let's allow the ball to spawn again so let's go back into our scorekeeper script and say no duck Q free so let's delete our ball after we we delete our ball we can go into our network manager and set our has Spa ball spawned to public and now we're just going access that I know it's cheating but I'm going to do it this way for just this project get tree. root. getet node network manager and let's get it from our node name which is network manager and do has ball spawn equals false so this should be called every time we delete our ball every time we score a goal so let's host and connect and we should have a finished pong game again if you notice the Jitter in here that's because perfect well thank you I hope you like this tutorial please like And subscribe if you want more tutorials like this in the future thanks guys
Info
Channel: Royas
Views: 344
Rating: undefined out of 5
Keywords: Godot 4, Game Development, Pong Clone, Online Game, Godot Tutorial, Multiplayer Game, Godot Engine, Beginner Game Dev, Coding Tutorial, Game Design, Indie Game Development, Game Programming, Online Multiplayer, 2D Game, GameDev Tutorial
Id: hynPwslw9U0
Channel Id: undefined
Length: 39min 24sec (2364 seconds)
Published: Fri Dec 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.