hey guys and welcome back to a new tutorial series so essentially this is online game development with python which means we're going to be using sockets and networking to connect what's known as a client and a server or multiple clients to a server where they can send and share information and therefore we can create an online game so we're going to start off with just the absolute basics and just get shapes for example like if i move a shape on my computer it moves a shape on your computer like if you're the other client and then we'll start getting into some more advanced stuff where we create a legitimate game and start sending mass amounts of information to the server and back to the client so we'll start uh really simply by just getting everything working on our local network and then once it's working on our local network we'll deploy that to an external server which will allow us to play from anywhere in the world not just against people on our local network okay so what i'm showing you right now is actually an online game that i created with python pie game and networking and this is similar to something we're going to make obviously not as advanced but it works on the same principles so essentially i have what is known as two clients now if you don't know the way that any online game works is we have multiple clients connecting to one main location which is known as a server now right here on my screen we have two clients so this client on the left that my mouse is kind of going over that has this red highlight like where the rook is or where i just am about to move this knight is client one and then this black one over here so like ui block uh where i just moved this pawn is client two now you can see in the background i have this command line thing going and it's sending and receiving information and this is essentially how a online game works and you might see uh whenever you guys play an online game it says waiting for server or connecting to server and that's because it's doing exactly that it's waiting to get a connection to the server and then grab information from that so that's the way that we're gonna be doing things is using a client and server now i'm not gonna be using any frameworks that are pre-created like uh i know there's like twisted and some other frameworks for python the only module we're gonna be using that's external as pie game and that's just to create some very basic graphics okay so let's close this i just want to give you guys an example of what an online game looks like and you can see when i was moving something on one client it would move it on the other so let's close that up and let's actually get started with the tutorial no it did not mean to open that so i'm gonna be working with pycharm uh for this tutorial now if you don't know what pycharm is it's an ide uh to download it all you have to do is just go to the internet type pycharm and you can go here and click download whenever it loads up now if you guys don't want to use pycharm that's absolutely fine you can do everything using the standard editor like idl you could use you adam use whatever you want but if you want to follow exactly with the tutorial i'm going to be using pycharm now the next thing we're going to need um other than ide i guess you don't need pycharm is we're going to have to install pygame now for 90 of you the way that you're going to be able to install pi game just by going to command prompt loading it up like this and just typing pip install pi game and then hitting enter now if this doesn't work for you i'll put a card in the top right hand corner of the screen right now which tells you where you can go to install pi game and i have a video explaining you exactly how to do this and if this command doesn't work for you you can follow that video and i'll explain to you how to do that so once we have pie game then we're ready to actually start writing a bit of code so while i launch up pycharm right here and create a new project let me just tell you about i don't know some of the things we'll be going through in this tutorial series so obviously we're going to be working on coding both a client and a server and i'm going to explain obviously exactly how those things work and how we can create them and then what we're going to be doing is we're going to be dealing with a bit of server like administration if you want to say that so actually deploying things to an external server um distilling in pen installing dependencies uh working with like a linux server to deploy our game to and that will be at the end of the series that we do that right now we're just gonna be working with what's known as localhost which means that we're going to be doing it on our own network so right now the games that we create are only going to work on our uh what do you call it against people that are on our wi-fi or on the same network as us and then later it'll work against anyone in the world that has that client downloaded okay so let's just create a new project here my new project i'm just going to say is tutorial i would say network tutorial 1 or something and just as a what do you call it here just letting you guys know i did actually mess up my thumb a little bit it's kind of swollen so if my typing is not the best that is actually my excuse for that so now that i've got a new project open i'm just going to create a new python file let's just call this tutorial one actually let's call this client okay and just save that as okay because that's all we're gonna be coding in this video is just a very basic client uh okay so now we've got client so what i'm gonna start off by doing is creating a configuration for my client and keep in mind if you guys are using something else you don't have to worry about what i'm doing with this pie chart specifics this is just the way you have to set up a project in uh pie chart so i'm just gonna set a client i'm gonna go to script path network game client okay apply okay now quick side note all the code that i'm about to write is available on my website techwithtim.net usually i have as well as that a text-based tutorial version i'm not sure if i'm going to be able to write the text-based tutorial while this first tutorial is out but you will see it on there at some point import tutorial import pi game uh but yeah all the code will be available in there in case you guys missed something or something's not working so we're going to start by importing pi game and make sure that that's working once that's working we're going to create a window so to do that we'll just say win equals pi game uh dot display dot update all right what am i saying pie game dot display dot set underscore cap set underscore mode wow a bit tired today guys and then in here we're just going to type width and height and then we're going to create these variables so we'll say width equals 500 height equals 500 okay so there we go with height win and now we're just going to set up a few global variables that we're going to have to use after we create a caption so let's just say hi game dot display dot set underscore caption and then here we'll just give it a caption let's just say clients okay all right so now let's set up a global variable that we're going to use and what we're going to do for this global variable is it's going to hold the current like clients we're going to say like client number and we'll just start by making that zero but we're going to increment that based on like once we connect to the server which we'll do later okay so now that we've done that uh there's a few basic things this is what we always do for like a pie game project or whatnot just going to define redraw window okay and in here all we're going to do is just pi game dot display dot update like that and we'll also fill the display before we do that oops didn't mean to do that uh with win dot fill uh and we'll just pick a color in this case i want to do whites which is 255 255 255. okay now yeah i just realized this is actually gonna be a lot harder to type than i thought because my thumb so just excuse me guys if i'm making a few mistakes here okay so we got our redraw window now and what we can do next is we can um code our main loop so i'm going to say define main and then here i'm just going to create a game loop and this is going to run continuously while our program is going and it's just gonna be what's checking for collision checking for events can constantly asking the server for information and you guys will see how this works in later videos more so we're gonna say run equals true and here we'll say well run and we'll just set up some very basic things that we always do for pi games so for event in pie game dot event dot get okay and then all we're going to do is say if event dot type equals equals pie game dot quit with all capitals then we will simply do pie game dot quit like that i don't need a semicolon i guess we can say run equals false as well okay uh for events that looks good and then what else we'll do in here is we'll just call that redraw window function so redraw window like that now what i'm thinking we should do next is probably set up a class for our character okay now our character is going to be just the only object we're working with right now and it's just going to represent like a rectangle that moves like left down up right around our screen and i guess we'll do that all in this video moving that character around and then we'll connect it to uh the server in the next one so let's create a class and we'll do that up here and we'll say class player uh like that okay so i'll give it a knit function and if you guys don't know much about object oriented program and programming and you want to learn i do have a tutorial series on my channel um that i would recommend you go through if you don't understand a lot of the stuff that i'm doing right now okay so x y with heights will be what we get in here and this is just going to represent actually let's give it a color as well because that'll be good to have x y with height color and yeah this will just represent kind of our player and what variables they're going to have so we'll pass these values in when we create a new player so self dot y equals y this is very straightforward self.width equals width and self.height equals height and finally self.color equals color so these are just our initialization here uh this is what we're going to use when we're drawing the character when we're checking for a collision or stuff like that and what i'm also going to do to save us a bit of time in the future i'm going to say self.rect equals and then in here let's do this okay so x y width height like that okay and this will just make it a bit faster when we're trying to draw our character so the next thing we're going to need is define draw now in the draw method here we're going to take a window so we'll call that win and all we're going to do is just draw a rectangle that represents our character onto the screen and obviously be the appropriate color so to do that all we have to do is just say win dot oh no we don't have to do that we have to do pi game dot draw dot rect standing for rectangle we have to first give the window so we'll give win we need the color so we'll do self.color and then we need a rect which will be self.wrecked okay and that's actually all we need to do to draw the rectangle to the screen now we need one more method we're going to use and it's going to be called move and move actually i believe yeah we don't need to do anything else in there right now uh as a argument sorry so for move what this is gonna do is it's essentially just gonna check um what do you call it if they press like left key right key what not how can we move them around the screen so the way that we can do this really basically essentially is just do pie game dot uh what do you call it dot keys dog get underscore pressed i believe that's it it might be key might be keys we'll see we'll see which one works so this is essentially going to give us a list of all of the keys actually a dictionary of all the keys and essentially each key is going to have a value of either 0 or 1. now if 1 is true that means we're currently pressing the key if zero is uh there then it means we're not pressing the key so the way that this is useful as opposed to doing what we could sometimes do which is just check for events in here is if you're pressing more than one key at once it'll allow you to move like diagonally or whatnot okay so what we can do in here now is we can just check if certain keys are pressed and then change the x and y values accordingly so we'll say if um what do you call it oh i guess we should probably put this in a variable let's just say keys equals pi game dot maybe i feel like it's key we're going to go key for right now pie game dot key don't get underscore so we'll say if keys and then pie game dot k underscore left standing for our left arrow key and that's all we need to do for that one and then we'll say if keys and then hi game dot k underscore is this should this be all capitals i think it should be okay underscore right and then the next one if keys pi game dot k underscore up and then our last one obviously is down and then we'll change our values accordingly inside of these if statements so pi game dot okay underscore down okay so left right up down so if we press the left arrow key obviously what we have to do is subtract from our x value so do that we'll just say self.x minus equals self.l now val is something we need to define so let's do that up here self.bell equals and let's do a value of like three for right now okay so if we're going right we need to add to our x so we'll do this very similar so self.x plus plus equals self.vel okay if i could type that correctly and then to go up we're going to subtract from our y value so self.y minus equals self.l and to go down we'll do self.y plus equals self.bell and that's the way the coordinate system works in pi game our coordinates actually at the top left hand of our player or our screen so if we want to go down we have to add to it and then left and right is the same in terms of subtracting and adding okay so that should successfully move our player we can add like a jump and stuff in here at another time but for right now that's all we need i'm trying to think of anything else that we could do right now um we should probably create a player object and draw that to the screen just to make sure everything's working so to do that let's create a player um should we do it up here let's do it right above our main loop here okay so we're just going to say or actually we'll do it inside the main loop this will work better we'll say uh p standing for player just equals player and then we'll give it some value using x y with height color so for x y we'll just start him at like 50 50. and then for our width let's just do 100 by 100 so he's nice and big and we can see him and then we'll do a color of green so that would be red green blue like that so 255 for green and then what we're going to do actually is we're going to type in here insert in redraw window we're just going to pass p to our uh redraw window so we can draw him and before we do that we'll call p dot move and what this will do is move our character based on what keys we're pressing so inside redraw window let's add a player um what he called argument attribute whatever you want to call that um sorry parameter that's the correct name and then we'll just say player.draw like that and we'll pass win in here which probably should be passed in here as well because we do use win quite a bit so let's do p let's do win and then p okay so let's run this now and see if i made any mistakes i likely did process finished oh we're never calling the main function so let's call this main function from down here so we're actually executing that code that we wrote and there we go so now we have a little green square and you can see interesting it's not working for me to move this around so let's check this one more time p dot move what is move doing get pressed let's just add i want to add something here and make sure this is working so let's we're gonna say clock equals pi game dot time dot clock okay and then in here we're just gonna do clock dot tick uh and we'll do 60 fps i just want to see if this is working if not i do know how to fix this um okay so we're not able to actually move this oh i know why so very interesting we are not updating this rect but we are updating um what do you call it like up down left right so at the bottom here all we're going to do is just redefine our erect by doing self.x self.y self.width and self.height now i'll really quickly explain why this error was happening essentially we're defining rect up here based on the input parameters when we're creating our player so that means we're always just constantly drawing our rectangle in the same position because we're never updating this rect variable we're only updating like x y with height right so we just have to redefine a rect variable every single time that we're moving which is fine and we can do that so now let's see and we can move our green square around the screen i actually quite like the speed this movement um so yeah so essentially in the next video what we're going to be doing is i'm wrapping it up here is we'll add a little bit more to this client and then we'll start working with sockets so we can connect this up to a server and we'll start talking about all the networking aspecting then so in this tutorial we're going to be working on coding the server and then in the next video we're going to be connecting this client that we made in the last one to that server and then sending information to and from the server uh so let's get started and let's create a new file that is going to be our server file so i'll just call this one server.py and then in here we're just gonna have to import a few things and i'll talk about exactly what they're gonna do for us once we start using them so let's start by importing sockets or socket then we can import underscore thread and we'll also import os okay so actually not os sorry sys that's all we need for that so what we're going to be doing like i've talked about is we're going to be using sockets and threading to handle connections to our server and essentially what that means is we're going to set up a socket and it's going to allow for connections to come into our server on a certain port so we're going to start by just defining a server which is going to be a string and port which is going to be a number now for ports you guys probably know what ports are you might have heard them before for example like a common port you would use on uh or common port that is used like on your router would be port 80 and that is for http connections there's also a port like 443 there's there's tons of other ports that have distinct uses but there's also a ton of ports that don't have any uses and that are just left open for programs like this or for different things to be used for so what port i'm gonna use which is typically open um it depends on like what router you're using and your internet connection but typically a port that's open is five five five five um so we're gonna use this port to connect to and from and it's just a safe port to use as opposed to trying to use another number uh that we might not know if it's being used for something else or not okay so once we've done that we've created a server and created a port what we're going to do is we're going to set up what's known as a socket okay and we'll talk about exactly how this works in a second but we're just going to say s equals socket dot socket and then here we're going to type something that's probably going to mean nothing to you but i'll talk about what it means so we'll say socket equals af uh underscore inet okay and then socket dot sock stream like that all right now these are just the types of connection so since we're going to be connecting to a ipv4 address which again we're going to keep talking about all this stuff as we go through in case you guys are unfamiliar with networks uh this is the type we're going to have to use and sockstream just i believe represents um like how this server string comes in i could be wrong on that but um this is the type we're gonna use and for any kind of applications like this this will be what you use for your socket okay so we're just initializing that and now the next thing to do is to bind our server and our port to the socket so to do this we need to do a try and accept and the reason we do this is because like i talked about we don't know if this is actually going to work initially doing it there could be in some instance this port is already being used for something and if that's happening that means that this is going to fail so we need to try and accept this so it will accept uh what do you call it uh error as e so we say socket dot error as e and we'll just print that out to the screen just so we know why we're not working there uh otherwise what we'll do is we'll say s dot bind and then here we're going to put server comma port okay so we'll bind to whatever i p address we'll put in here to this given port okay so i hope everything's making sense so far essentially what we're doing when we do sockets is we're setting up a connection or we're using a port on our server on our network it's going to look for certain connections and then we'll be doing this on the client side as well will be binding or not i don't know if it'd be binding we'll just be connecting to a certain server and a port and then since we're connecting to that this server script that we're going to have running we'll see that connection and handle it in some way okay so now that we've done that i'm trying to think what else we have to do okay so what we're going to start by doing is we're going to start listening for connections so we're going to do s dot listen now s dot listen essentially just opens up the port so now we can start connecting to it and having multiple clients connecting and whatnot so in here this actually takes one argument now it's optional and if you leave it blank it means it'll allow for unlimited connections to happen now depending on what kind of program you're writing is what you're going to do for this now for me i only want two people to be able to connect to my uh what do you call it yeah to my server so we're just gonna do s dot listen to now this might actually be one because it might be like zero one but i think two may be the correct thing so do s dot listen for now uh and then what we're gonna do is we're gonna print after we listen uh we'll just say waiting for uh connection and we'll say server started or something like that because once we get to this point we are running the server and everything actually is working like we're listening for connection we're ready to go okay so the next thing we're going to do is we're going to define something known as a threaded function okay and we'll i'll talk about again what this means um but let's just do threaded uh threaded underscore client for now and i'm just putting you don't actually have to name it this you can name it whatever you want i'm just putting threaded here just so we know this is threaded and then it's going to take one argument which is just going to be conn which stands for connection and let's just pass in there for right now so the way that threading works actually let's let's do the threading and then i'll talk about how it works because it'll probably make a bit more sense so let's do a while true down here okay so once we set up our server our port we bind it doing here we're starting to listen waiting for connection starting the server then what we're going to do is we'll be get put into this while loop and what this while loop will do is we'll continuously look for connections okay because right here we're just listening uh like once right to see if anything's on that server report but down here we want to continually try to grab connection let's see if something's connected and if it does then we want to print something to the screen or we want to send information or we want to start a new thread which we'll talk about in a second so in here what we're going to do is we're going to say connection uh which co n and then adr equals and then s dot and then we'll say accept and what s dot accept is going to do is it's going to well accept any incoming connections and then it's going to store the connection and the address and the connection is by the way an object representing like what's connected the address is going to be an ip address in these variables okay so if we get a connection what we'll do is we'll say print connected to okay and then atr and this is just going to show us what ip address is actually connecting so we can have a look at that and then what we're going to do is we're going to do start underscore new underscore thread and then in here we're going to do uh what was that name of the function that we had was threaded client okay and i believe we do comma and then in brackets here we do con like that okay so start new thread is there a reason that's not working um give me a sec guys i want to see why oh that's why so up here instead of saying import thread we're going to say from underscore thread import star okay and that's just going to make it so we can just do this start new thread thing and you know what i don't know if we're going to need this sys but let's just leave it there for now okay so let's talk about what threading is going to do so essentially the way that you guys are used to programs working i'm assuming unless you have some familiarity with threading is that say we're in this while loop right and we were to call the function threaded client well before we continue going with this while loop we would have to wait until this function was done running in other words we return back from this function some value or for example like he does like x equals five we would have to wait for this x equals five to execute and then it would come back in this while loop and keep going now we don't want that to happen because we're going to be having multiple connections going at once so what we want to do is we want to start what's called a thread and a thread is just another process that's running in the background so that just means when we do start new thread and we do threaded client it's going to run this function but it's not going to need this function to finish executing before it continues the while loop so this is going to be running in the background as like process 2 while process 1 is still running and still going so that means say we connect to 100 different things we're going to have a hundred different functions running so 100 different threaded clients on the stack or like keep going and then what we're going to have is this while loop still continuing to go what did i just do i'm still continuing to run to look for another possible connection you guys will see more how this works but essentially just means this will run in the background and we don't have to wait for it to finish executing before we can accept another connection that's the basic kind of way to that works so now let's start working with threaded client and then we will uh test the server out and see if it's working and then obviously in the next video we're going to connect to it and do all the connection stuff okay so in here uh threaded client so what should happen when we connect to uh a client well we're gonna have to do a while open here so we're gonna say wow true because we want this to continually run while our client is still connected okay now what we're also going to do is we're just going to say reply equals blank like that and i'm just copying from my other screen because this one is a bit finicky i don't want to mess it up we're going to put a try in here and what we're going to say is we're going to try to receive some kind of data from our connection okay from whoever is connected we want to receive some kind of data so what we'll do is we'll say i believe it's uh s con dot receive that might be right yeah i think that's right and then here we're going to put the amount of bits okay now if you guys know anything about computing you know like how what bits represents but essentially this is the amount of information we're trying to receive now if you're getting an error when say you'd like do this and you connect up and you get some area that says um what do you call it like object was truance or like uh you you're getting any errors just increase this size okay and you can just do that by like putting this like times eight or something just note that the larger this size is the longer it's going to take to receive information and that's obviously because the more information you're getting the longer it takes to send that over the server so 2048 bits is not a lot it doesn't take very long it happens almost instantly but if you bump this number up to a ton then it will take uh longer to do that okay so data and we're gonna say reply equals and then we're gonna say data dot i think it's actually string string.decode let's see this oh data.decode because it'll be in that that kind of object for that data.decode and then here we're going to do utf comma 8. now the reason we have to do this is because whenever we're sending information over a like client server system we have to encode the information and you'll see that in the next step that we're going to encode information before we send it back to the client but that means that we're receiving encoded information so to actually be able to read it like as a human readable string we need to decode it first so it's really easy to do that we just do decode and we're just giving the format which is utf-8 okay so reply equals that and then we're going to say it's going to say if not data we're going to print disconnected okay and then we're going to break and this just means if we try to get some information from the uh what do you call it the client but we're not getting anything we're going to disconnect and we're going to break and that likely means that we've well disconnected from the client or the client's left or something like that so instead of continuing to run this while loop and trying to get information from a client that's disconnected we're going to break this is just kind of a fail-safe to make sure we don't get into any infinite loops and it's also going to show us if we're running into any issues with like receiving the data and decoding it which we'll talk about later okay so otherwise so if we are getting information all we're going to do is we're going to print uh received is that how you spell received maybe uh and then we're going to put what do you call it reply okay i didn't mean to do that let me see if i'm spelling this right i'm not okay received reply so this just means we received from the client uh this reply let's print it to the screen see what it looks like and then we're gonna print sending uh colon and we'll just print reply okay and then we'll talk about this again in a second why does this keep happening okay reply next now after this uh if not data breakout what we'll do down here is we're going to say con dot send all and we're going to send str dot encode reply now again remember that since we're sending information over the server we have to encode our information so all this is going to do is just encode our string reply into a bytes object so that means when we read it in from the client side again we'll have to decode that information it's kind of annoying but i mean it's a security thing right so now we're just going to accept uh i guess what kind of error would it even be i don't even know if there's gonna be any errors if we run into anything let's just break uh just to make sure that we're not you know getting in that infinite loop or we're not gonna ruin the program by doing that okay so this is actually about it for our server uh let's see how much time we're at 13 minutes okay so now what we need to do is figure out what the server number is and then we can actually test it and see if this is working uh so what we're going to do now is we're going to find the server number now to do this we're going to be doing this over uh localhost okay that means that our we're only gonna be able to connect over our local network meaning that like anything on our wi-fi network um that can see each other that'll work fine but as soon as we go outside that network it won't work so we're gonna be using what's known as local ip addresses so to find the local ip address of the machine you're currently on you're going to go to command prompt in the bottom left and then you're just going to type ip config okay now some of you guys are probably freaking out because you can see my ip address right now this is a local ip address and that means that it is locally assigned to my network no one outside of my network can see this ip address or companion or can ddos it or anything like that okay so it's perfectly fine if you guys see this address or if other people know what this local address is okay just as a note so what we're going to do is we're going to take this ipv4 address so just copy that and we're going to paste that inside of the string here okay so 10.11.250 is mine now yours likely is like 192.168.something okay but since i'm on like a massive network usually they use 10.10 like as the default gateway which is what they're using so my p address starts with a 10 yours likely starts with 192.168.1 or dot like 5 or something like that and then the rest of it okay so that's the address we're going to use and this is going to be our server address so whatever machine that you're going to be running the server script on that's the address you want so say you want to run this server on your laptop and you want to run clients on like your pc and your mac or something like that then you want to make sure you get the ip address from your laptop and you're putting it in that script okay and we'll talk about more of this in the next video when we actually connect to it okay so now that we've done this i probably made a mistake but let's actually just create a configuration quickly for server uh and run this and just see if we're getting any errors as of now now it is worth noting that we're not going to be able to connect anything yet um so there's not really going to be much we can see or really do but for now let's just test this out so let's have server let's run this and you can see he's waiting for a connection server started so that's actually good if you're getting this string of text everything is currently working uh in the next video we'll probably have to debug a little bit once we start connecting to this but for now that is the main server script now i'll briefly just talk about before i end this video how it's going to work in terms of running the server script and running the client script the server script always has to be running okay so whenever you're trying to connect you have to have first run the server script and then you can run multiple client scripts from wherever on the network you want now the server script has to be running on the machine that the ip address is like this little string here okay it has to be running on that machine and you can run a client script on the same machine that the server script's running and you can run multiple client scripts on the same machine so like for example what i'm going to do to test this in the next video is i'm going to run the server and then i'm going to run two clients on uh this machine and we'll see that it like is moving back and forth for them so what we're going to be doing in this video is we're going to be coding the uh kind of client side of this so connecting to the server i know we already coded a client but we're going to code like the network aspect of the client so that it can connect to the server it's not as much code it's a bit more straightforward and then we're just gonna test out sending very basic information to the server and hopefully getting some back see if that's working okay and then in the next video we're going to be connecting this so like the little user interface we created with moving that block around in the first video we're going to be connecting that um so that we can have multiple clients running and we can see like different blocks moving on each screen okay so that will involve a bit more work um hopefully by video five we'll have like a fully working kind of game that's working over the network okay that's the goal so within this video i just want to start by saying on this server class here or sorry server file i did actually forget two lines of code in the last video so after this accept break in threaded client just need to add this print loss connection and then connection.close all this is doing is once we break out of this threaded client we're just letting the we're just gonna print this to the console so we can see what it looks like and then we're going to close that connection um so that we can possibly reopen it in the future okay really straightforward that's all you got to add so just make sure you add that before moving on okay so next what we're going to do is we're going to create a new file and i'm going to call this network okay now you don't have to put what i'm going to in a new file it's just a lot easier so that's why i'm going to do that so let's do network and in here we're going to import socket now what i'm going to do is i'm just going to code a class that is going to be responsible for connecting to our server this just makes it like so i can reuse this class in the future and you guys could reuse this class in the future and it's just a bit cleaner and nicer and that's why i like to do things so i'm going to say class network again call this whatever you want and in here we're just going to set an initialization function uh we'll take actually is network do we need anything in network uh no i think we'll just leave like that so we're going to say self.client equals socket dot socket it's going to be the exact same arguments as last time so let's say socket.ifnet i think is that what it is if underscore net uh af underscore inet okay and then we'll do socket dot sock stream like that okay now we're gonna define the server and the port again so self.server equals uh self.port equals five five five five now for the server this again this number has to be the same as the one you used in the server uh what do you call it the server file here so no matter what like no matter where you actually are um like what client you're using this number is gonna stay the same because this is the server you're connecting to it's not the client's address we don't actually have to define the client's address anywhere it'll automatically get that for us okay so what we're going to do now we have client server port we need to do this self.adddr equals and then we're going to say server so self.server and then self.port in here okay and then self dot what do you call it self.id is going to be equal to self.connect okay uh now you guys actually let's just do self.connect for right now and we'll talk about why i was going to add this id later once we add that functionality to the server okay essentially i wanted to have an id that was returned here or like that was stored in this network object just because we are gonna have to like be sending an id to each of our clients so they know if they're like player one or player two but we'll do that later um because we don't really we can't really do that yet okay so we've called this connect method so we need to write that now so let's say define connect okay and in here i believe we should probably be given actually it's probably fine just use self right now and what we can do is use self.client.connect okay and then here we do self.addr now we're going to throw this in a try uh and accept just in case you know this isn't working so we'll say try say accept uh and this is gonna do socket error um let's say accept and we'll just pass right there okay just in case this doesn't work so we'll try this we'll try to connect accept pass now once we actually connect what we're going to do is we're going to return i'm just looking at my other screen right now self.client.receive and then we'll do 2048 dot decode okay so what this is going to do i'll talk about this because it might be a little bit confusing is when we connect we want to actually send some kind of information immediately back to the object that connected to us so like for example it's going to ah i didn't mean to close that let's go into server here and you can see when we initially connect we're not sending any information until we receive something now that's fine but when we connect we should really send some kind of like validation token or like id back to our network object or back to our client so what i'm going to do in here i'm going to say con dot send okay and then in here what we're going to type is let's see what should we really type here um str dot in code and then here we'll just say connected like that okay uh just so we know that we did indeed connect so that means if we set this equal to a value so self dot i don't know let's say id equals self.connect what'll happen is when we connect we'll return that string connected so this will get connected and since it's encoded we need to decode it obviously so if we want to print actually in here self.id it should say like connected okay let's see if that works okay so now that we actually have that um let's see if we can connect to the server and then we'll deal with sending information from the client to the server as opposed to just getting it from the server okay i know it's a bit confusing right now i'm just trying to figure out the best way to do this um so let's try this okay so we're gonna say n equals network we'll just type this at the bottom of the script uh we won't do this after we'll delete this just for testing purposes and then we're just going to say actually that's probably all we need to do because it'll just print our id okay so let's create a configuration for network so new configuration type network in here and then select that path and then let's test if this is working so remember what i said when we're going to connect right to our server what we have to do is first run that server script so let's run the server script here waiting for connection server started okay let's run this network script now uh invalid argument was supplied s dot listen to okay so i had a quick look here i realized the mistake was i was actually running this server two times so obviously that's not gonna work for us so we can put two back in this listen i'm not sure if you guys we'll see if i left that in the video or not uh but let's go to network and we also need to change this to af instead of if i don't know why i typed if i literally said af when i was typing it but that's fine uh and we have server i'm actually running it right now so make sure you guys run that and then let's run network and see if this works okay sweet so i know it doesn't seem like much but you can check here if we go to server it says connected to and then gives us that address and it's also printing out some other thing that i honestly don't know what that means and then saying disconnected and lost connection sweet that's actually really good and that means that we're everything is working and you can also see that we have connected being printed here so that means when we connect to the server we're actually getting the value that it's sending so we're getting this uh connected and we're printing it out uh decoding it all fine so that's really awesome so now the only next step is to actually send information to the server and keep like a loop going like sending receiving setting receiving setting receiving now let's actually just test um if i run this again uh you can see again obviously it's working again so this is the server just continually is running i don't actually have to stop this unless i want to make modifications to it so let's just keep that running for now and let's add something to our network class so in our network class we're going to define a method that's going to be sent now this method is going to be very useful later on because it's going to save us a lot of time so in sand we're just going to take a string which is going to be data okay and all we're going to do in here is we're going to try to dot client dot send and i'm gonna say data str actually dot encode data and then we're gonna get a reply from that server so we're gonna say return so exact same thing that we're doing here client i receive uh 2048.2 code and we'll accept and i believe this is a socket error yeah it is socket dot error as e and just print e so if we get into some error where you know either we're sending or we're receiving it's not working let's just print that arrow up to the screen so we have a look at what that really means so now let's do a test and try to send information to the server and then get something back okay now the information that we're getting back should just be the same information because that's what we have in server we're just going to send exactly what we got right back right so um it doesn't make sense right now to do that but we'll talk about like what we can what valid information we can send how to send receive information in the next video when we connect up the client uh to the thing okay so what we're going to do is we're going to say n dot send and we'll print n dot send okay and we'll print n.11 again and let's just send like a few bits of information and see if everything is indeed working okay so n.send and then in here let's just type hello and we'll type working okay and see if this works so we have actually we should have yes server is working let's run our client and you can see we get connected hello working and if we come here it says received hello sending hello received working sending working so it's awesome um that means our network class is working sending information receiving information is working server is working and now the only thing that's left to do essentially is to connect that up to this so use this network class in some meaningful way here and then to actually store information on the server and then send that information to multiple clients which we'll be doing in future videos what we're going to be doing is we're going to be hooking up our graphical client to our server so we can send information back and forth and ideally at the end of this video what we're going to have is we're going to have two rectangles on each client so we'll have like two clients running and when you move the rectangle on one client it moves on the other and vice versa okay so you guys will get the idea when we go through but there's a little bit of work we have to do and we're gonna be modifying a few things within a lot of the files we've already created so just make sure you guys are paying attention and again if anything is going wrong feel free to download all the code off of techwithtim.net uh it'll be available there and it'll be exactly the same code that i'm writing right now okay uh so first thing we're gonna do is in this network class we're just gonna delete a few things so this testing stuff we don't need anymore this print statement for the self.id we don't need that and we're actually going to change this self.id to be self.pause okay and you guys will see why we're doing that in a second and we're going to add one quick method in here and we're just going to say define get pause okay and all we're going to do here is just return self.pause all right and again we'll you'll see why we're doing that but i just don't have to come back to this network class so we'll do that right now okay so from inside our client now what we're going to do is we're going to import this network class because we're going to use it in here so we're going to say from network import network and then in our main function down here what we're going to do is actually above player we're going to say n equals network okay like that and then what we're going to do is we're going to say start pause equals n dot get pause so essentially why i'm doing this is because when we first connect to our server what i want to happen is i want it to return to each of our clients the starting position of their character right or of their cube okay because it's going to depend where they're starting based on if they're player one or if they're player two so then on the client side what we're gonna do is when we initially connect to the server which is what we're doing when we create this network object we're connecting to the server we're gonna get that starting position and then for creating our own player we're going to use that starting position to determine like where we're starting so the position is going to come in as a tuple all right and we'll be coding all this on the server side in a second but it's easier just to go through each file rather than going back and forth it's going to come through as a tuple that looks something like this it'll be like 50 100 okay um so what we're going to do is we're going to read this tuple in because it's actually going to come in as a string like you'll see how it comes in we're going to get the two aspects of it's like the x value and the y value and then we're going to use that inside of this player initialization to like set the initial position so that reminds me what we're going to be doing when we're sending information to the server is we're going to send it using string data right and that's what we're doing in the last video is we were sending everything with strings so we were sending like hello and then we were decoding it and encoding it now this is not the only way we can send information we can actually send information with objects and i'm going to show you the advantage of doing that in the next video but for now we're just going to send strings so since we're going to be sending strings the strings that i want to send are positions okay i want to from each client send the current client's position to the server the server is going to get that position update it on the server side and then send the other client's position back to um the client you guys will see how it works in a second actually let's see if i can do a quick drawing to illustrate this because it'll make things a bit easier okay let's i don't know why i had this let's delete that okay so let's do a quick drawing so we're gonna have is we're gonna have client one and excuse me because i'm drawing this with a mouse and client two okay so it's gonna be one and this is gonna be two all right this will do it as a red box is gonna be our server and on the server what we're going to do is we're going to store positions so it's like one has position like one two okay sorry this is hard with the most guys and then client two will have position like three and one okay so it's going to store these positions so what's going to happen is when we initially connect client 1 is going to go to the server it's going to connect to it and then it's going to be sent back the starting position for the client okay so it's going to be said okay so you're client one so that means you're gonna start at position one two client two it's gonna connect it's gonna say okay we're client two so i need to send client two's position so let's send that back all right now let's say we've already connected client one's there clients two is there and we've set their starting positions what we're going to do next is now we're going to continually call to the client and update the position so what we're going to do is say let's it's say we're working with client one okay what it's going to do is it's going to send its position to the server so it's going to say let's just say pause okay it's sending its current position let's say that position is like four uh five sorry this is really hard with a mouse okay four or five what's going to happen here is we're going to say okay so you're updating your position so then it's going to go in here it's going to say okay client 1 will update your position to be 4 5 like that okay and then what it's going to do is instead of sending back the same position because we already know what the position is it's going to send back the position of client 2. so it's gonna send three one and then on here we can draw that client so that it looks like um it's moving right so we're getting we're sending our information and then in return we're receiving the other client's information now the same thing works here with client two so if client two connects right and it's sending information it's gonna send its position let's say it sends the position one three okay that's its updated position so this is gonna change to be one and three and then what's gonna happen is it's gonna say okay well we don't need clients two's position we need clients one so what's client one position well that is four or five so let's send four five over to client two and then on client two we can draw four five so you'll see they'll simultaneously be moving i hope that makes sense i just want to draw it out for you so you guys know what i'm about to do in this video okay perfect now the only thing is we need to send these positions as strings so we're actually going to have to implement two helper methods so that we can convert those positions which are going to be tuples into strings and then we can also read the string into a tuple so what we're going to do is we're going to say define and i want to remember what i call this one we'll say this one is read underscore position which means we're going to take a string value and we're just going to read the string in so we'll say str equals str.split and we'll split it at a comma okay and you guys will see how this works in a second and then what we're going to do is we're simply going to return the end of string zero so str zero okay comma int of str one so what we're gonna do is we're gonna take a string in that looks something like this it'll be like 45 comma 67 okay in in string value 45 67 we're going to split it which means we're going to get a list that has the string 45 and the string 67 and then we're just going to convert those to ins and return them as a tuple so now we get that converted to something that looks like this which is useful information that we can actually use okay so that's what read pause is going to do but we need to make one more which is going to convert that position into a string so we're going to say make underscore position and in here what we're going to have is we're going to take a tuple so let's say top standing for tuple and what we'll do here is we'll say um let's see here return top actually sdr of top zero and then we're gonna add that comma in so sorry i'm butchering my typing right now comma plus str of top one and i hope that makes sense how we do that so that's returning the string value so we're reading pause and making pause and that's all we need to do for those helper functions okay so that means though that when we get the position initially from our server it's going to come in in that string value right it's going to look like 45 67. so we need to convert that so what we'll do is we'll say read pause and we'll just put that around n dot get pause because it's going to return to us that string position so we'll read it in and now what we're going to do is for our player we're going to say start pause zero and start pause one okay and what this is going to do is just set it to the initial start position we're going to code all the server stuff after it'll start making a lot more sense okay now what we also need to do is we need to create a second player because we're going to have to draw the first player and the second player on the screen right so we're going to say p2 equals and we're literally just going to copy this except for start position we're just going to put it as zero zero for right now and we'll update that in a second okay so we have p p2 um and for now that's what we'll do actually let's we can continue working in here so that we don't have to do anything else in here after we'll just code the server side so what we'll do now is we're going to send our current position to the server right that's like the algorithm we've developed essentially we are when we connect we're going to get the starting position we're going to set that starting position and then every time after that so like every time the frame updates we're going to send our position and then get the other person's position so we're going to say is we're going to say um p to pause is going to be equal to n dot send okay and we're going gonna send make position of and then what we're gonna have to do in here is it's a little sketchy but we're gonna do p dot x p dot y now right because that's the position of our player the x and y coordinate we're putting it in tuple form we're sending it to the function make position which is going to turn into a string and then we're sending it to the server right okay awesome so i think that makes sense and then what we're going to do simply is for p2 we're going to update is its position so we'll say p2 dot x is going to be equal to uh actually n2 dot send but we're gonna have to put around here sorry is make pause read pause because right it's coming in as a string so we need to convert this into our actual position so f p two pause is going to be p2 position 0 and then p2 dot y is going to be equal to p2 p2 pause 1. okay now the only thing that's left to do here is what do you call it draw p2 and update p2's rectangle so what we're going to do now is in the redraw window down here we're going to put p2 we're going to go to redraw window we're going to say player 2 here and then we're going to do player 2 dot draw window because again it's going to be a player object so that'll be fine and then last thing to do is just update the rectangle so what i'm going to do is i'm going to say p2 dot update and we're going to go to player object now we're just going to add this one function that is update and then so you see i just made like self direct equals x y with height and then in here i'm just going to say self dot update like this okay so i know this might be getting a bit confusing but we're almost finished let's go ahead and do the server side and then we'll recap through everything what we've done explain things i kind of have to get this content out uh okay so define update so what we're doing again here is before we just had this line of code here um so we're just replacing that with an update method uh that's pretty straightforward i hope that makes sense to you guys and that's just again so when we change the x and we change the y value of p2 directly then we are updating the rectangle so when we draw it to the screen it's in the correct position okay so i believe that's all i have to do for the client side so now it's time to go to the server side and the server side is pretty straightforward now the server needs to keep track of the positions right it needs to hold player 1's position and players 2 position consistently so we can decide if we want to store that let's say like on a hard drive or if we wanted to store that in memory now in our case it's not a lot of information so we're just going to store it in the memory of the server right so what we'll do for that is we're going to create a list and we're going to say pause equals and just a blank list and this list is going to hold the positions of our players now actually that reminds me we're going to put two tuples in here and these are going to represent sorry the starting positions of our players so we'll start with zero zero and like a hundred a hundred so player one will start at zero zero player two will start at a hundred hundred okay and that's all we're going to do for that little list there and then what we're gonna do down here uh well this while loop is we're gonna keep track of how many players have connected in our case we only want two to connect right and then we need to keep track of well those players so we're going to say i said current player equals 0. now this is because when we connect we're going to add 1 to this so that when we go back into this function it'll be you guys will see how it works but essentially every time we create a new connection so every time this we accept a new connection we're gonna add one to our current player so we'll actually do it at the bottom of the while loop we'll say current player plus equals one this is just to keep track of which player we're using so that we know what position to update what position to send to that player based on the connection right okay so keep track of current player and now what we're going to do is when we start this new thread so this threaded client we're also going to pass another argument which is going to be the current player so instead of just passing connection we're also going to pass player in here okay uh current player like that okay because that's going to be important information to know all right so we're actually almost finished we just got to update a few things so let's actually grab these two methods from our client class or client file and throw them onto server here so we're just going to put them right above position because we're going to need to use them read pause and make pause so now when we initially connect to our player right this is what happens when we initially connect the first thing that's sent is this encoded message that is connected now in our case what we want to send is we want to send the starting position so how do we do that well we know what player we are we're either player zero or either player one right because we only have two players when we start with player zero after player zero connects then we do player one right so what we'll do is we're gonna send pause player now that won't work because it's just a tuple right we need to first convert that to a string and then encode that string and send it so let's actually go back here i want to keep this string down in code so string.encode and we'll say make underscore or pause and then we'll just put pause player in here and what that'll do is it'll convert it into a string for us and then it'll send that uh to the player for us right and then they'll read that string in convert it to position and update the position accordingly okay making sense hope so okay so that's how that works for player now the only thing we need to change now is what information we are sending um every time this loop is running right every time we receive something from the player we want to send back the other player's position so to do that what we're going to do is we're going to say con.receive.decode so we'll get rid of this for now and then what we're going to say is we're going to turn this data into like readable a readable tuple right so to do that uh we're going to use the read position method that we've already created or function so say read pause con.receive and we'll turn that into from that string like this right or whatever it was like 45 67 we'll turn that into something that looks like this so that we can actually use it okay so now that we have that it's turned into that what we're going to do is we're going to update our current player's position so we're going to say pause player equals data right because this is the position they sent to us so let's update it on the server uh so yeah so it's updated information okay sweet so we've done that now all that's left to do is send the other player's position back to our client so to do that what we can do is simply say reply equals and we're just going to say pause or actually uh let's not do it up here let's do it down here okay we're going to say if player equals equals one so if we're player one we're gonna send player zero position right so we'll say reply equals and then pause player uh or not pause not not player zero sorry and then else we're going to send so we'll say reply equals pause one okay so if we're player one we send player zero position if we're player zero we send players one position right like i was talking about with that little algorithm we're going to use okay and then instead of saying received and sending actually yeah we can say received reply sending reply or we'll say received data sending reply that should work fine okay uh now what we'll do is we're gonna send all the reply but the thing is our reply we need to first convert into a string so to do that we're going to say make underscore pause right that function we've already created and then that should actually be about it now i'm probably made a mistake or two here but let's just test this out and see if everything's working so let's start by running the server and then let's run two clients and see if we can connect if there's any errors okay so we've connected with client one let's run client two and let's see what happens so i'm on client one right now you can see that when i move my green square it moves on the other client okay let's go to the other one and would you look at this when i move it on here it moves on the other client so we have successfully set up and connected our two clients together now the only thing i want to change quickly is just the color of these so that we know who is who like which square am i um so to do this we're just simply going to go we'll actually close the server class otherwise you're going to run into an issue or server instance whatever it is go to client and instead of having the same color here we're just going to change this to be 255 for player 2. and i want to show you what happens because some of you are probably going to be confused with what's about to happen here but it's kind of interesting so let's run server let's run client one let's run client two now notice that these colors are inverted now can anyone think of why that might be so green right is gonna be your current player so right now i'm on here i'm on this where my mouse is and i'm moving the green square that's near the middle of the screen okay but notice on the other screen it's moving the red square that's because on your client it's unique to you so on your client you are green and red is the other person meanwhile if i go to this client and i start moving see green is me and red is the other guy right and he's not currently moving now if i wanted to move these at the same time i would just have to be running these on different computers or i would have to change like the arrow keys to move them and that's just because obviously right like if i'm pressing the arrow keys on here it's not going to work on this client but if i were to load up my laptop and try doing it on there this would work fine as well there's quite a few issues that we may run into when we're doing this so i've set this up essentially to be kind of like an example program or like an example problem um to give you guys an idea of the way we go about doing things in terms of server and network but it's really not ideal the way that we've coded things so far now i did plan this for uh to do what we're about to do but essentially i'm going to redo what we've just done in a much more elegant and nicer way that's going to allow for a better scalability of this program okay so what we're going to do is i'm going to redo it here i'm going to show you how we can actually send physical oh not physical but like send objects to the server and from the server back to the client rather than just string data and then in the next videos we're actually going to scrap all this code that we've written and we're going to start from fresh and code like a networking game it's going to be a lot more complex than just a few squares moving around the screen so that's my plan for this series let me know what you guys think of that i know it might be a little bit frustrating to get rid of this code but now that we understand how a lot of this works it's going to be really fast to rewrite it in a much more elegant way so uh what i need to first start by doing is just taking this player class okay and i'm just going to copy it into its own file so really straightforward i'm just going to go to new python file i'm going to call this player with a lowercase and then just copy that player class in there and just import pie game up here okay import pi game now i'm just going to go back into client we can delete this player class now and what i'm going to do really basically is just from player import player like that okay and that's the first step now remember i said we're going to send objects so that actually means that we're not going to need this read pause and make pause thing and it's kind of annoying how we've had to well take that tuple object decompose it turn it into integers and then change object properties and then when we want to send something we got to put it into a string and we got to send it in just a pain and we don't want to have to do that especially when we're sending tons of different bits of information not just that same positional data right so we'll get actually going to delete this we can delete this client number i don't know why i have that there um and we're going to start just making some modifications in terms of sending data and receiving data so we'll start on the client side and then we'll go over the network uh the server side and fix some of that so wherever we see like read pause and make pause we can just get rid of that for right now um we don't actually need any of that we're not going to need this p2.x stuff uh we don't need p2.update we'll we'll get rid of all this for right now and you know actually let's get rid of start position let's get rid of p and let's get rid of p2 and we're going to recode all this okay so actually um p2p that can stay there p dot move is fine okay so we got rid of all that and you can see we've just cleaned up this file bit and we'll start working with some more stuff in a second now what i want to do actually is go to this network file that we have and we're going to start making some modifications in here as well so what we're going to be doing is we're going to be sending objects so that means we're going to send like an instance of the player class and that's actually what we're going to be sending instance of a player class to our server as opposed to sending like string data and then updating the object on or then updating the string data on the server and then sending it back and then updating the object it's just a lot of work it's a lot easier just to send the actual object so we can do that using something called pickle okay now it's a weird module name but it comes default with python and this allows us to do something that's called serialize objects and that just means we turn it into byte information which is like all the zeros and ones send it over the uh what do you call it send it over the network and then we can decompose that turn it back into an object and use that it's really easy to do that so what we're going to do here is we're going to modify a few things in our network class so first thing instead of having self.pause we're going to say self dot p okay it's gonna be equal to self.connect instead of saying get position we'll just do get p and then we'll return self.p okay and that's all we need to modify for that but now in the connect in the send we're gonna change a few things as well so since we're going to be getting object data what we have to do in the connect is we have to decompose that object data so to do that you do pickle dot loads okay now what this stands for is a sense for load byte data okay and we'll we'll talk more about this as we keep going through but that's essentially what it means and same thing here in send instead of encoding this data what we're going to do and i guess decoding as well is we're going to um dump it into a pickle object and then send it so to do that we're going to just say pickle uh is that a pickle yeah dot dot dumps like that and we'll just put data in there okay and then when we receive we'll do the same thing as before we'll say pickle dot loads and then we'll load that in so now essentially what we're doing is we're going to be receiving an object decomposing that object getting the actual object not the bytes form of it and then we're sending it we're gonna first like what do you call it encrypt it like send it into that byte information and then on the server side we'll decompose that as well okay so we'll we'll go through that but that's all we need for the network side so now let's go to server and start making some modifications so same thing here we no longer need this read pause and make pause functions we're not going to be using those and we don't need this pause list either we're going to change this actually to be players and it's going to be equal to two new players so notice that we're going to actually store the player object on the server as opposed to on the client side and this is not only like safer because it means that the player technically can't really mess with the player objects they can only like do commands to update them um but it's also just like it's gonna be a lot easier you guys will see how it works we're gonna say player and we'll do another instance of player and in here what we're gonna do is we're just gonna create two new players so we're gonna say zero zero fifty fifty and we'll give it a color in this case the first color will be red so we'll say red green blue like that and for the other player we'll start about a hundred a hundred like before we'll do fifty 50 and then we'll make his color uh blue why not so do that okay so now you notice that we're getting a little error for player here just because we forgot to import it so to say from player import player like that uh and that's why i made this new file by the way just so that we'd be able to see it from the server side and the client side as well and then wherever we're doing this like send encoding stuff we're going to change this so let's do that now actually so instead of con.send instead of encoding some string information we're just going to send the player object so what we'll do is we'll say players like this and then player right so exact same kind of concept as before in that we're going to send the initial like starting position of the player or like the but in this case we're just setting the initial player object which means any information that's stored in that player will be given to the client as opposed to just the position okay so next what we'll do is instead of saying data equals read pause and decoding we're going to get rid of this.d code and we're going to put pickle dot loads okay and actually when i'm sending this player object my bad here guys we gotta do pickle dot dumps okay and then we're just gonna have to import pickle up here so import pick all right sweet okay so pickled out loads pickle.dumps and that is obviously instead of pause player equals data we're going to say player players player equals data and again same concept as before what's going to happen is the what he called the client is going to send us a player object we're going to replace the existing player object with that new player object and then we're going to send back the other player objects like the other clients okay so now what we're going to do is just change these pauses to be player or players like that okay same thing here players and then when we send it back what we'll do is we'll just turn it into a object right so we'll just do that pickle.dumps and send it back so say pickle.dumps reply like that and that should actually be about it so let's go back oh sorry there's something we need to do in client um so now what we're going to do is essentially we've set up our network class so that we're going to be able to send that object data we've set up the server so we're going to be able to receive that object data we're going to modify the objects we're storing in the list here and then we're going to send back the other ones to the other client so in clients all we have to do now is set up player 1 and player 2 and then send that data so really straightforward it's very similar to before what we're going to do first of all we're going to say p1 or actually just p i guess is equal to n dot get p okay because in the network class remember what we're doing is when we initially connect so let's go back to server we're just going to send the initial player object which is going to be whatever player it is so 0 or 1. so let's just say that this client's player object is going to be n dot get p okay and then we'll say actually i think that's all we have to do for yeah that is all we have to do for that inside this while loop now what we're going to do is every frame we're going to send this player object which will be updating with p dot move and we'll just get the reply and say that that's p2 so we're going to do is going to say p2 equals and then in this case we'll just say p dot or not p n dot send p and that's all we have to do and notice here that we don't have to do with all this like make what he called make pause read pause all that stuff and i believe this should be working if i didn't make any mistakes let's cross the fingers and let's try this out uh waiting for connection let's go to client one run that okay and client two running that and now notice that these rectangles are the same color and watch what happens if i move this red one see how it's red on the other screen as well now that already shows us one of the advantages of doing it this way is that we can store information like color as well not just position and if we wanted to store maybe like there was a text attribute on each of these players we could store that as well if we wanted to store more information in the player like a health or something like that it'd be a lot easier to do that by just sending the actual player object that has like an unlimited amount of attributes rather than just sending that little tuple that has like five six right which is the position so the reason i went through the trouble of showing you the other way is to show you the massive advantage of doing it this way and just to give you kind of perspective if you're making something really simple and you don't use any objects that's how you can do it with string data but i think this way is a lot easier and we've just cleaned up quite a bit of code we've gotten rid of a bunch of functions and moving forward this is going to make things a lot easier for us i'm pretty much going to be gutting everything we already did we'll keep a little bit of it but we're just going to really add to a bunch of that and just yeah we're going to be gutting most of it and we're actually going gonna be working to create online rock paper scissors now i know this sounds like kind of a lame game but let me show you because it's actually pretty complex and if you can understand how to make this game then you're gonna be able to understand how to make any other kind of online game because the principles are the same in terms of sending information waiting for players to go and there's a lot of different things that you might not think about that we actually have to do to code something like online rock paper scissors okay so let's this is client number one i'm just running another pie game window or pie charm window with the server running on it you can see obviously it's been oversized but it says waiting for player okay so i'm going to launch another client and then excuse me you can see when i launch that it loads both of them up into the game and it says your move opponents you remove opponents and currently it's waiting so i believe this one's player two and this one's player one so if i make a move here on uh let's say rock it'll lock in my move it says your move is rock and then over here it says obviously the opponent's move is locked in because it's like looking for this guy's move and now if he makes a move like let's say scissors then it says you win you lost and then it just resets and you can keep playing games now i'm also going to be adding more to this this is just like the beta version i'm going to have wins ties and losses keeping track in the top hand corner and when you load in you're going to be brought to a menu screen which will allow you to like start a new game or to leave or we'll add that later as we go but this is the main functioning game and you can see obviously it's working well tie game and it restarts this also allows for unlimited amount of clients to play so for example if i launch another two windows you can see these guys now have their own game going it's kind of difficult because i can't really get four on the screen but anyways if i go like scissors paper that works independently of these games and these games can kind of play at their own time which is really interesting and really cool and if you disconnect one of them it automatically disconnects the pair and that's just because uh obviously you can't play against no one right so yeah okay sweet so that's that um let's start getting into the code okay so first thing we're gonna do is we're actually going to code a a game class okay and this is just going to be responsible for holding all the information for our game that we need so for example did player 1 go yet did player 2 go yet what move did player 1 make what move did player 2 make are both of them connected to the server information like that and you guys will see how much information we actually need it's also going to store things like keeping track of who won or who lost how many ties how many wins so that's what we're going to do with this game class so let's start making it so class game i'm doing this in its own file by the way um just called game you are going to need it in its own file because it's going to have to be accessed by both the client and the server okay we're going to define our initialization uh in here we're going to take id i'm going to say self dot p1 went equals false self dot p2 went equals false and obviously you guys know what this is going to do it's just going to stand for if player 1 has made a move or not if player 2 has made a move we're going to do self.ready equals false if i could type that correctly we're also going to add self.id so self.id equals id and this is going to stand for the current game's id so each game we create is going to have its own unique numeric id so that we can determine who's like what clients are a part of what game and whatnot we're going to do self.moves equals and then we'll just do none and not in here because currently the moves are none but we'll just store two positions so we can change that we'll say self dot wins equals and then zero zero obviously this one is going to stand for player one this one's gonna stand for player two and we'll say self.ties equals zero that's all we need for the init so the next one is going to say get underscore player underscore move now what this is going to do is exactly what it says is just going to get i don't know how i added that there you're just going to get the player move that we asked for so we're going to take p which is going to be either 0 or 1 and we're going to do is simply return self dot moves and p and just to remind ourselves we'll say that p is in the range of zero and one so we're only going to take value zero or one and then we're going to return uh a move so let's say move here okay and that's just to remind ourselves that we have to pass zero one obviously zero is going to represent player one and one is gonna represent player two okay next one play so this one's a bit more complicated not crazy we're going to take play we're going to take a player and we're going to take a move and what this is going to do is it's simply going to update our moves list with that player's move pretty straightforward so what we're going to do here is we're just going to say if player equals equals 0 then what we'll do is we'll say self.moves 0 equals move um oh actually you know what let's do this sorry i'm just looking at my other screen right now we'll say self.moves player equals move but now what we have to do is based on the player we have to update if p1 went or p2 went okay so what we'll do in here is if it's player one obviously we'll do p1 went um equals true i'm gonna need to self before that and then we'll call we'll just do a little else here because it's not player zero it must be player one so we'll say self.p2 want if i could spell went equals true so that'll just keep track of if we've gone or not sweet next method this one's really easy it's going to be called connected and this is going to tell us if the two players are currently connected to the game if they are it will allow us to load in and that's how we can determine whether we should show waiting for player or not on the screen right so we'll say return self.ready and that's just going to tell us obviously if we're ready and that will be updated from the server side which we'll do later next method define both went this is just simply going to return if both of our players went so to do that we're just going to say self.p1 and why can i not spell that word and itself.p2 went like that okay next one is winner this one is a bit more complicated but it's just going to keep track of where it's actually going to tell us who's won the game so if we call this method we're assuming that both players have gone we're going to check their moves excuse me against one another and see if they want so we're actually going to have to check nine possible cases because there's three moves each player could do three times three nine so what we'll start by doing is we'll just say p1 equals self.moves zero dot upper and then zero the reason we're doing this is because we just want to get the first letter of the move because the move is going to be stored as rock paper or scissors the string and it's just going to be easier for us to type out for example r or s or what do you call or p to check the moves as opposed to having to check the entire word so we're just going to get that first letter by doing move zero we're going to upper it and then we're going to take that first letter we're going to do the exact same thing for p2 except obviously we're going to need um oh i don't know what i did there we're going to need moves1.upper and now we can start checking to see who's won so we're going to say to start winner is equal to negative 1. now that's because there could be no winner there could be a tie so if it's tied we're gonna say negative one if player one is the winner it's gonna be zero if player two is the winner it's gonna be one okay so we're gonna do is we're gonna say p1 equals equals r and p2 equals equals scissors what we'll do is we'll say winner equals zero because player 1 won that we'll say l if p1 equals equals s and p2 equals equals r then we'll say winner equals one i believe do another lf and i know this is tedious but this is the way you have to check for rock paper scissors i don't think there's an easier way to do it if you know an easier way let me know and p2 equals equals r and if you guys don't want to type this you can always copy it from my website techwithtim.net okay so say winner equals paper beats rocks that'll be winner equals one or zero sorry we'll say lf p1 equals equals r and p2 equals equals p then winner equals one and we've just got two last ones to check here so we'll say l if p1 equals equals uh s and p2 equals equals r and then p2 is the winner so winner equals one i believe that's oh sorry i'm going to mess this up this should be p think so p rock rock paper scissors paper yeah winner equals zero um okay l if p one equals equals paper and p two equals equals scissors then winner equals one and i believe that should be correct one two three four five six okay sweet and then the other cases are if it's a tie so if none of this is the case then they must have tied and then all we're going to do is simply return winner like that okay and one very last method then we're actually done with this class we can move to something else is define reset went and all this is going to do is say self. p1 went equals false and self.p2 went equals false pretty straightforward and this is the game class i know i kind of sped through this but it's pretty trivial how this works uh we just need to get this out of the way so we can start coding some other stuff okay sweet so we've done this class um next thing i think we want to work on is network so network actually you guys are going to have to modify yours to look like mine now get p and uh what do you call it so this first half so init and get p are going to be the same as what we had previously the only thing that's changed is connect and this send so in connect instead of um what do you call it like unpickling an object so like pickle dot loads what we're simply doing is we're going to just connect to the client like we did before but instead of unpickling it we're just going to decode it so we're going to say self.client.receive2048.decode would return that value and that's because when we initially connect to the server what we're going to get from the server is our player number which means we're either player 0 or player 1. now that's important because that's going to determine where on the screen we're drawing certain things and how we're sending information back to the server and updating player one or player two right because technically each player thinks that they're player one but each one needs to be assigned either a zero or one by the computer so we know where to store information right okay so that's how we modify that just do decode instead of pickling i'm sending i believe is the same except what we're going to do is instead of pickling an object to send we're simply going to send a string and we're going to load an object so that means we're going to send string data to the server and we're going to receive back object data so when we receive something we have to pickle that loads it in but when we're sending it we just have to encode the string okay so just make sure it looks like this i don't think i need to go through this we've already done this for the past two three videos and that's the network class so game and network are done the next things to do are server and client now server and client are a bit more complicated so inside of server i guess we could do this first because it doesn't really depend on the client to work where the client kind of depends on the server we're gonna change a bunch of things so this is what mine looks like now i've kind of gutted the entire threaded client i got rid of most of the stuff like most of the other stuff i just left this beginning thing so that the server ip the port um the socket connecting listening waiting for connection so by the way some of you were saying you're having issues with f s dot listen you can just make this zero it doesn't really matter what's in here and some of you were saying like you're having issues just you can just delete it and type it in again and apparently that works that's what someone said so i don't know don't ask me about that but if you're running into issues do that okay so what we're gonna do now is we want to make it so you can have unlimited connections at once now that means we're going to have to have unlimited games running at the same time so before what we were doing when we had those players moving around the screen we were just storing like player 1 player 2 and we just had a list that had two entries that's how we were doing that what we're going to do now is we're going to have a list that contains a bunch of different games and those games actually are sorry it's going to be a dictionary those games will be accessed by their id and you guys will see how this works um it's a bit complicated but just follow along um and yeah so i gotta just open up my other file so i don't make any mistakes here okay so what we're gonna do is we're gonna do uh connected equals set we're gonna define some variables we'll talk about what these do games equals a blank dictionary and id count equals zero so the reason we're adding these is games this dictionary is going to store our games so it's going to have an id as a key and the game as like a game object like this okay as the value this connected is just going to store the ip addresses of the connected clients we're storing in a set just so it's easier to access later i don't actually know if we use this we might um but we'll see okay id count obviously is just going to keep track of our current id so that means what game we should recreate so we don't override games and say like two games have the same id because obviously we can't have that happening okay so that's fine for that we're not going to deal with anything threaded client right now we're going to go down to our while loop and this is where we're going to create new games based on new people joining or possibly delete games actually we'll delete games from threaded client so we're going to do right now is when someone connects this this runs right and we run a new so like once we accept a connection everything after this runs so what we're going to do is we're going to say id count plus equals 1. if you notice me looking away i'm just looking at my other screen to make sure i don't make any mistakes on this now what id count plus equals one is going to do obviously is it's going to keep track of how many people are connected to the um the server at once because obviously right like once this happens we accept then we go down the while loop we start a new thread and then we wait for another connection so we're just going to keep track of that what we're going to do is we're going to say p equals 0 just standing for the current player we're going to say game id equals and this is going to be weird but just follow along with me uh we call it id count minus one integer division two now what this is going to do is essentially every two people that connect to the server we're gonna increment game id by one and what game id is going to be or we'll say it's yeah we'll add it by one what game id is going to do is keep track of what id our game is going to be so like for example if we have 10 people connected to the server we're going to have five games right so that's what this line of code is doing for us it's keeping track of how many games or if we need to add a new game because obviously if we have like six people connected all of them are gonna be playing each other a seventh person connects well it doesn't have a game to join we have to create a new game for it to join hopefully that makes sense okay so what we'll do next we'll say if id count modulus 2 equals equals one and what this is going to stand for is if you're going to be player 1 or player two and if this happens is actually we need to create a new game because this means that we don't have a pair for our new player so for example like say this number is three that means two people are already playing so that's one person just connected so we need to create a new game that's what this modulus 2 is getting okay so to do that we're going to say games game id equals game game id okay and i believe this actually has to be capital so obviously uh sorry at the beginning of this i forgot to mention i imported game so from game import game that is important and yeah essentially what we're doing is we're just going to say that game id which is that key in our dictionary is now equal to a new game so we can access that and add players to it and whatnot sweet so that works let's actually print out a message here and just say creating a new game dot dot just so that in our server we get some kind of output and we can have a look at that if something's going wrong so otherwise if there we don't need to create a new game meaning we have let's say three people are connected so that second game already exists and another person connects well that person has to be a part of this new game so what we're going to do then is we're going to say games game id dot ready equals true now what this means is that the second player connected so there's two players now connected to our game so now we can say that that game is ready to start playing because both the players are connected so that means that they can we'll obviously play against each other right so that's what we'll do we'll set that dot ready equal to true and obviously we're storing all the games on the server side as opposed to on the client side and then what we're going to say is we're going to say p equals one and what this means is player equals one and you'll see why we need to do this in a second okay so now we're gonna do start new thread now notice and start new thread i added two new uh parameters p and game id so this means the current player so it's either player zero or player one and the game id and game id is going to stand for which game in this game's dictionary are we playing in this threaded client like which one of our clients that's connected here uh is playing which game that's why we need that so let's pass that information so we're gonna pass p which is either gonna be zero or one like we have there and we're going to pass game id and then we'll have that up here and just remember that threaded client one of these functions is continuously running for every single one of our clients so if we have a hundred clients we have a hundred different functions of this running in the background at the same time okay awesome so that's how that's working inside our threaded client now excuse me i try to take a break there inside of our threaded client we now need to add some things so the first thing we're going to add is id count we're going to global id count because if someone leaves our game or disconnects we're going to need to subtract from that so we can keep track of accordingly like how many people are connected how many games are running and all that stuff okay now the first thing we're gonna do when someone connects to our uh what he called our server is we're gonna send them what player they are remember what i was saying in this game class or in this network class story then when we connect we're initially just going to decode a string that's either going to be 0 or 1 to tell us what player we are okay so what we're going to do is we're going to send con.send str dot in code p and i believe this should be actually string p like that so that we know for player 0 or if we're player 1 that's the first step next we're going to say reply equals a blank string i'm going to say wow true and this is where we're going to start doing some more serious stuff in here so the way that it's going to work in terms of sending string data from our client to our server is we're going to send one of three different options we're going to send get we're going to send reset or we're going to send a move and the move is going to be like rock paper or scissors so if we send get what that means is we want to get the game from the server so we're going to send that every frame we're going to send get that string get and then the server is going to look and it's going to say okay what are you sending you're sending get all right we'll send you back the game that's how that's going to work another option is reset reset means reset the game the game has finished both players played reset and that's going to be sent from the client side because the client knows when we want to reset right the last one is a move same thing when the client makes a move so like rock paper scissors if they are allowed to make that move which we'll check on the client side we'll send that move to the server the server will update the game accordingly and then it will send back the game to the client and that's how that's going to work sweet so what we'll do now is we're going to say well true i'm going to say data equals con dot receive and then we're going to say 4096 in here instead of 2048 which we're using before dot d code the reason we're doing this is just in case uh we're setting too much information that is more than 2048 bits we want to just double this number so we can get more if you run into any issues that say like pickle data was truanced or like ran out of input just increase this number okay you can literally just do multiply by two in here and that should hopefully fix the error if it doesn't work you can like multiply by four multiply it by eight um and that should hopefully fix your error for you okay so now what we're going to say is we're going to say if game id in games now i'll talk about why we're doing this in a second but we're going to say they're going to say game equals games game id so essentially every time we run this while loop we're gonna check if the game still exists and that's what we're doing right so in this games dictionary we're seeing if this game id which is the key to access the game is still there now why would we check that well if one of our clients disconnects from the game we're actually going to delete that game from the uh what do you call it the games thing now what that's doing for us excuse me is not only like keeping track of our memory which means that we're not going to just continually keep creating games so like say our server ran for weeks and we never deleted any games then we'd probably run run out of memory on our computer right if we're playing a lot of games but it's also going to tell the other client that was connected to that game that hey this game no longer exists that means the other person must have disconnected from it so we have to do something accordingly go back to the menu screen right do something like that okay so that's we'll do there and then we're going to say in here is going to say if not data we're going to break this similar to before so i'll go through it a bit quicker we're going to say else and now we're going to check the three different things that could have been sent right so we've received the data so we're going to check if we got reset get or if we got a move so first thing we'll check we'll say if data equals equals reset okay and we're going to say if data does not equal get and then else sorry this should be an l if i left out it does not equal yet else we'll do something else uh actually do we need an else no we don't need else okay so if data equals reset what we're going to do is we're going to say game dot reset right because we already have the game and if we look in here what reset's doing is essentially it's resetting both players once we can play another game really straightforward for that next one if data equals get what we're going to do is say game or if data does not equal get sorry so if it didn't equal re reset and it does not equal get well then it must be a move so it means we're either getting rock paper scissors so we're going to send that move to the game to update it so to do that we're going to say game.play and then we're going to do the current player number which is p and then the move and the move is going to be whatever this data is right so it would be data okay and then otherwise so i guess after that um what should we do here we'll say reply equals game and now what we're going to do is we're going to do con dot send all i'm going to say pickle dot dumps uh and not doubt sorry reply okay and what this is going to do let me just make sure i didn't run into any errors here is simply going to package up our game into that nice um sendable form we're going to send it over to our clients client's going to receive it unpickle it and then use it to obviously make moves and do different things and draw it to the screen and all that okay all right so i think that makes sense we can go through it really quickly uh what time are we at 25 minutes all right so we'll go through really quickly essentially what's happening when you connect we're going to check if we have an even amount of players or an odd amount of players if it's an odd amount of players when you connect that means we need to create a new game so we create a new game if it's not that means we need to assign you to a game so what we're going to do is make the current game that only has one player in it ready we're going to assign you to that and start a new thread when we start the new thread what's going to happen is we're going to send to the client what player they are either player 0 or player 1 and then what we're going to do is we're going to constantly receive string data from the client if the game still exists then what we'll do is we'll check if they're sending us reset get or remove if they're sending us a move we'll make that move they're sending us reset we'll apply that reset to the game and then we're just going to constantly send back to them the game object and now what we need to do is just really quickly add some else statements in here so that if some of this stuff doesn't happen we have like a catch for it okay so what we'll do here is we're just going to simply say else break okay that should be lined up here and we're just going to add a try and accept up here so we're going to say try and we're going to indent all this by just highlighting and pressing tab i'm going to say accept and then pass i think that's yeah no not passer accept and then break just in case you know something goes wrong with this data dot receive we want to make sure the server keeps running so we have that try and accept and then underneath this accept in line with the main function indentation what we'll do is if we break out of this while loop we need to close the game and delete it so to do that is actually we're going to print uh some on my wrong file here we're going to print lost connection and then we're going to print what do you call it closing game okay and actually we can print that game id too if we want to see what game id we're closing so we'll say lost connection closing game game id okay and then we're going to try to delete games game id otherwise we will accept and pass okay and then underneath here last thing we're going to do is say id count minus equals 1 and we're going to say connection dot close now that i actually think about it we should probably put this closing game only in this try after we delete just so that we don't we only close the game once we don't say we're closing the game twice okay so what we're doing down here essentially is if we break out of this while loop so for example if the game no longer exists uh we're gonna break if something goes wrong with this getting data so like the player disconnected we're gonna break we're gonna say lost connection we're gonna try to delete that game the reason we have this try here is because if both players disconnect at the same time one player will delete the game before the other so if we try to delete a key that doesn't exist we're gonna run into an issue so we try that if that works we will say print closing game and then we'll say that game id otherwise we're going to pass we're going to subtract from the id count and we're going to close the connection sweet so we're rolling we're going pretty fast here now all we got to do is code the client now this is probably the most amount of code i think it's about 100 lines it just is a lot of drawing stuff okay so i'm going to take a break we'll be back in one second and we're going to code the client all right so i'm back now and we've got about 150 lines to write for this file it's pretty tedious because a lot of the stuff is to do with the drawing like we need those buttons to be working we need um like all that text to be showing up so that's like 90 or not 90 but like 70 percent of the code we're about to write it's just going to be cosmetic stuff um but i mean what do you want me to tell you that's what we need to do if we're going to make an online graphical game right so uh let's start by just coding a class and this is going to be a button class uh just that when we have those three buttons you know it just makes things easier so we're gonna do our init uh what do we need in the init i'm gonna go for uh text sorry i'm coding in the wrong file text x y and color and we're just going to say that the width and the height will be uniform in here and we'll just make it the same for all of our buttons so we're going to say self dot text equals text self dot x equals x uh self.y equals y and self.color equals color okay sweet we'll also add a width and a height here so we'll say self.width equals 150 self.height equals 100 and feel free to play with these numbers that's just what i decided by the way guys um just really want to say this i'm not focusing on how good this game looks i know it looks like crap but you guys i know can go through and tweak the colors and tweak the positions and all that i just didn't want to focus on that because i want to get the hard stuff out of the way in the tutorial okay so let's do a draw method in here pretty straightforward we're just gonna do pygame dot draw dot rect and then for the rectangle we're gonna take window which is that parameter for the draw and then we're going to do what should we do color so self dot self.color and then we're going to need that rectangle position which is going to be self.x self.y self.width and self dot height like that okay and then i guess let's see if there's anything else we need to add to that no that's fine we're going to define a font so we actually need to make sure we just add this at the top pi game.font.net okay make sure you guys add that and we're going to do font equals hi game dot font dot s sys font should help if you spell font correctly and then here you're gonna pick your favorite fonts i like comic sans i'm gonna make this how big should this be uh let's make it 40 and then what we're going to do is we're going to render some fonts so we're going to say text equals font.render and we're gonna put self.text we're gonna do one and we're gonna do the color which will be i guess in this case black or white 255 255 255. okay next we're going to draw this on the screen now we want this to be centered on the button so i'm going to do some like i don't know decently complicated math uh it's not really that crazy but we're going to just say win.blit text and then we're going to say self.x minus uh is it minus no it's plus self.x plus in brackets and we're going to round in these brackets i know this is confusing we're going to do self.width over 2 minus round and we're going to say text dot get underscore width over two now what this is doing essentially is we're starting at our x position but obviously we want our text to be centered so to center our text we need to know not only the width of the like container of the button but the width of our text so we're going to get the width of our text our of our button we're going to subtract that from the width of what do you call it our text so that way it should add like 20 or 30 pixels from the left side so our text is centered okay for the y we'll do a similar thing so inside make sure you don't mess up these brackets inside here we're just going to actually copy this and we're going to paste it right after a comma and we're simply going to say dot y plus round self.height okay plus text dot get underscore height or minus text again height over two and that should center our button um yeah okay next we're going to say define click we're going to add a position here this is just going to tell us if we clicked on the button or not so it's a really basic uh if statement here so we're just going to say x1 equals pause 0 and y one equals pause one now what we're gonna say is gonna say if self.x is less than or equal to x1 less than or equal to self.x plus self.width and self dot y is less than or equal to y one less than or equal to self.y plus self.height i believe that's correct let me just check this uh yep that's correct then what we'll simply do is we'll return true indicating that we did press the button otherwise we will return false now i know i'm speeding through this but it just because it's really basic pi game stuff and we're doing online games so make sure i change that so i don't want to focus too much on the cosmetics but essentially what this is doing is it's checking if the coordinate which we're going to pass in here which is going to be a tuple of x and y of our mouse position is actually in the button and the way we're doing that is we're saying we go on the x right we check if it's greater than the x we check if it's less than the x plus the width so like if it's in between the little box and then for the y value we do the same thing but we're checking vertically to see if it's in that box if you don't understand that i have pie game tutorials where i go through like collision and how all that works i'm not really going to talk about that right now okay sweet so we've got that working now what we're going to do is actually let's see what i want to code now let's code the main function and then we'll get into redraw window so the first thing we're going to do is we're going to define those three buttons that we're going to have at the bottom of our screen so rock paper scissors do that we're going to say buttons equals and we're just gonna make three buttons first button will be rock so we're gonna say rock we're gonna start it at 50 500 and then we're just gonna go and give it a color of zero zero zero okay we're gonna create another button we'll say button and then we'll say scissors we'll give it a let me just check here 250 as an x 250 is an x 500 as y and for the color for that i got to check what color i made this i believe that i made that ah red okay so 255 0 0 and then one more button can anyone guess what this one is going to be it's going to be paper we're going to put this at a position of 450 so if we can go here 450 500 and we will simply make it blue or green sorry zero two fifty five zero so red green blue okay sweet so that should be it for our buttons um and now we'll get into the main function and start coding some stuff the first thing we're gonna need to do is going to need to say run is equal to false or is equal to true i always do that we're going to say clock equals pi game dot time dot clock capital c here my bad okay next we're going to say n equals network right because we're importing network up here we're going to do a very similar thing to what we did before in all the previous tutorials where we just connect initially by doing that initialization and then we're gonna say p equals actually player equals n dot get p right and you should already have that method um it's just returning that uh like connect what we connected to right so when we connect we get the player number which is either zero or one so we need that now it reminds me it's going to be a number so we got to put an inch around this so that we can compare it with other integers okay and last we're going to just print just so we have this you are player player now this just indicates to us like when we initially run if we know we're zero or one just to make sure everything's working fine now we're gonna make a while loop we're gonna say it's our main game loop we're going to say wow run and then in here we're going to do clock dot tick 60 very similar to what we've done before guys i'm going to start adding some new stuff in a second okay so now that we've done this it's time to start actually connecting and asking the server for information so what we should be doing here is every frame we should be asking the server to send us the game especially at the beginning of this loop because right now we haven't actually created a game class right we need to get that from the server so we're connected now we know what player we are so now what we can do is we can try to get that from the server so to do that we're going to say game equals n dot send get and that's literally as easy as it is we just need to do an accept and then we'll just uh we call it we'll say run equals false and we'll say print couldn't get game okay and the reason we're doing this and we're going to break as well is because when we if we send this and we don't get a response from the server that means the game doesn't exist and what what if that happens well then what we should do is we should exit out of this game we should print saying we couldn't get the game and then we should try to reconnect or start a new game with someone else so this main function is going to be like the actual game running but once we exited this main function we're going to go to a main menu and the main menu will allow us to choose like who we want to play against and a bunch of other stuff as well okay you guys will see that later okay so that's how we do that next what we're going to do is we're going to say if game dot both went now what we're going to do here is if both players went well we're not waiting for anything now we need to see which one won so what we're going to do here is we're going to check which player won and we're going to display that message accordingly on the screen so what we're going to do initially is we're going to redraw the window the reason we do this right away is because we want to make sure that if both players went we're updating um the window and on the window it'll check like if both players have gone like in this redraw window and it'll draw the player moves for us so you guys will see how that works in a second we're going to do a delay we're going to do pie game.time.delay 200 and now what we're going to do is we're going to try game uh sorry game equals adam.send reset now why we're doing this obviously is because well if both players went we need to tell the server to reset um those player moves right so inside a game if we call reset went we're just going to reset it so that we were able to play the next round after okay we're going to accept except of course i can't spell that we're gonna say run equals false we're gonna do the same thing as before we're gonna print couldn't get game couldn't get game and then we're gonna break okay now under this so after we send that reset now what we want to do is we want to display a message on the screen indicating whether player one one or player two one or like if you won or if the other player won so the way we're going to do this and it's actually a decent amount of lines is because we have to like render font and then we got to determine where we're going to draw the font and what's going to be on the font so we're first going to start by defining a font so we'll say font equals pie game dot font dot sys font okay in here we'll say comic sans font size let's go 90 for this one now we're going to say if game dot winner and remember if we go to game winner is going to respond to us with either a zero a one or a negative one so you have to check if winner is one and player so whatever our current player is one then we're going to say u1 if winner is one but the current player zero we're going to say you lost right so that's how we can check this so to do that we're going to say if game.winner equals equals one and player equals equals one and remember we got that player from the server so we know if we're either player zero or player one on the client side and uh is actually do i need an and uh oh sorry or that's what we need to do or game dot winner equals equals zero and player equals equals zero so essentially what we're going to do here is we're going to check if this player won so we know what player we are and we know what player won so if that coincide like what player we are and the player that won then we'll print out and we'll say or we'll put on the screen u1 right telling that client they want so we'll say text equals font.render and then here we simply say uh u 1 exclamation point and then we can just do one and then a color and obviously color we just do like red like that okay on the screen okay so else actually l if and now we're going to check if they lost well actually i think we could do this easier we're going to say l if dot winner equals equals negative one so if it if we tied what we'll do here is we'll say text equals font.render and we'll just say tie game exclamation point one again we'll put that in red okay and now else so if we didn't win and we didn't tie we must have lost so we can literally just copy this and we'll just say you lost as the text okay so you lost dot dot sweet and now what we're going to do is just render that font put it on the screen so or not render it just put on the screen so we'll say win.blit uh text and now we're going to do the exact same thing that we did before uh to get it in the middle of the screen just be a little bit easier so we're just gonna say i believe do i need another bracket so i don't think so we'll say width over two and that's the width of the actual screen minus text dot get underscore width we need those brackets over two we're gonna do comma and now we'll just do the same thing with height so we'll say height over two minus text dot get underscore height over to okay so that's going to put it in the middle of the screen we're going to update the display highgame.display.update and we're going to delay so pygame dot time dot delay and i'm going to put 2000 for two seconds you guys can put whatever you want in here okay so let's break this down really quickly if both players went that means now we get to check who won so what we're going to do is we're going to redraw the window we're going to what do you call it apply a small delay of 0.2 seconds just so that we can see what both players did before it immediately pops up who won and who lost so actually let's make this delay half a second we're going to send to the server reset so we're going to reset both players once so the next time that we start playing we can both players are allowed to move we're going to say run equals false if this doesn't happen if this doesn't work we're going to prank couldn't get a game we're going to break now otherwise so like if this worked we sent the game we're going to create a font we're going to check who won so either we won we tied it we lost we're going to display that to the screen we're in delay for two seconds and then we're going to play the game again after okay awesome so we're almost done we're just going to add this pretty actually complex for loop in here so we're going to do now is we're going to say for event in pygame.event dot get very standard for pygmy you've probably seen this before i'm going to say if event dot type equals equals pi game dot quit then what we're going to do is going to say run equals false and we're going to say pi game dot quit so this just means that they hit that little x button at the top of the corner now we're going to check if they actually press their mouse button down so this is how we're going to check if they pressed a button that's what we're going to do now let's say if event dot type equals equals pi game dot mouse button down then what we'll do is we'll get the mouse position to do that we're gonna say if we're gonna say pygame.pause uh pygame.mouse dot get underscore pause so what we're doing here is we're checking if they press right middle or left mouse button if they do let's get the mouse position now for every single button we're gonna check if we click that button if we did we're gonna do something accordingly okay so we're gonna do now i'm going to say 4 button in btns remember we defined buttons up here then what we're going to say is if btn dot click pause now if they did click the position there's a few things we need to check oh and elsa when you check this sorry and game dot connected sorry so what this game.connected is doing is just making sure that it's not going to let us press like rock paper scissors unless we both players are on so that's just so that we don't run into an issue where we can make a move before the other player connects okay so just add this and game.connected what we'll do now is we're going to check what our current player is because this is going to determine how we send a move so we're going to do now is going to say if player equals equal zero if not game dot what do you call it p1 went then we'll do something otherwise so we'll just put uh else here and we'll check if not p2 game.p21 okay so what we're doing now and i haven't coded the rest of it yet is we're just going to check if we press one of the buttons so remember we have that click method in our button that tells us if we clicked on it so if we do click on it and we're connected to the game what we're going to do is we're going to check if our current player is 0 or 1. now what we're doing is if we're player 0 well we're going to check if player 0 has gone yet if they've gone obviously we're not going to let them make a move right because they've already made that move they can't change their move once they made it same thing with player 2. so if we're not player zero we're player one clearly so that means we're going to check if player two is gone yet and if they haven't gone we'll allow them to move okay so what we'll do in here now is we're gonna make a move now to make a move remember we just need to send to the network our move so we're just gonna say n.send or to the server sorry and all we're going to do is we're just going to send the text of the button now the text of the button will be rock paper or scissors right and that's precisely the move that we're going to make depending on what button we're clicking so it's a really nice dynamic way to do that now once we've done that right so if we go to server what happens here is if we send that we're going to play that move and we're going to update it on the game so that the other client when it gets that game board again we'll have that updated move you guys will see how this works in a second okay so that's working well now all we need to do is just add in line with this right here we're gonna say redraw window we're gonna give it win we're going to give it what else do i need to give it game and p which stands for current player and that's actually it for and make sure you just call our calling main down here at the end of client that's actually it for this main function so now all we need to do is do redraw window and we're really close to done so we got another like 20 lines and then once we do that we're actually finished this game and then we can start testing it out and talking about some more things we can add to it okay so what we're going to do now is yeah this is actually quite a bit of work is we're going to draw all the stuff on the screen now so we've done all the logic aspect of it down here in this main function now we need to draw everything so it's more tedious and it is difficult but we're just going to first start by checking if not game.connected now this just means if we have not yet had the other player connect then all we're going to do is we're just going to print on the screen waiting for player and we're not going to show anything else so to do that we're going to say font equals pie game dot font dot sys font name obviously is comic sans and then the how big should it be let's make it 80 okay and then we're going to say text equals font dot render in here we're going to say waiting for player dot dot one color let's do nice red and let's actually add true here for bold okay okay so we're going to blit this on the screen so to do this we'll say win dot blitz and we're going to do again that same i know a tedious thing to get in the middle of the screen so we're just going to say with over 2 minus text dot get underscore width and then we're going to say height over two minus text dot get underscore height uh and actually we need to make sure we're dividing both the width and the height by two so let's do that okay that's it for that now else so this means if we actually are connected both players are in now it's time to start drawing the real stuff on the screen so we need to draw that what was it so actually let me pop up client for you guys so you can see what it looks like uh let's run the server rotten client client right so if we want to see the client what we should do is we need to draw this this this this and then the three buttons okay so we're gonna have to do these four texts and the thing is these texts need to change um on like they're gonna be different depending on what player is looking at it right so for example here it's showing us what our move is but notice it just says locked in for opponents it doesn't tell us what our move is and what the other players move is right so we need to do that as well okay so to do that uh let's start um we're going to make another font i'm going to say font equals pi game dot font dot sys font comic sans size of this font let's make it 60 and then what we're going to do is going to say text equals font dot render and we're going to do your move so we're going to start by just doing your move and like opponent move because those aren't going to change they're going to stay the same no matter what and for that we're going to do one and the color i had there was like a nice cyan i think right so we'll do this um feel free to change the color i know it probably doesn't look the best and let's just split this at a static position on the screen so we'll say text and let's go 80 200. okay all right next so actually still in this else statement we're going to copy this um just sorry what am i doing just this text and this win part and we're going to put it down here and say your move we're going to say opponent move is that how you spell that uh let's change that to opponents and actually let's just get rid of moves to be too big opponents and same color except we're just going to change the x value so that we draw it at what do you call it 380 like that okay so that's it for your move and opponents next what we need to do is bit more complicated because now we have to draw what the actual moves are so remember we're obviously we don't want to show the other player what one of the players moves is unless both of them have gone it's like we want to know what our move is but we can't know what the other players move is until we've both made a move so to do this what we're going to do we're going to start by just getting both player moves so we're gonna say game dot get underscore player underscore move we're gonna get move zero and we'll actually we'll copy this and just do move two and change this to one so we'll start by getting the moves and then now we're going to check if we should show those moves if we should show waiting or if we should show locked in okay so to do this we're going to say if game dot both went okay like that what we're gonna say is gonna say text one equals font dot render and we're just gonna use the same font as before and what it's gonna be is move one comma one comma and we'll make this black so zero okay and we'll copy this and we'll do the same thing except text two is going to be equal to move to so essentially this is saying if both of the players have gone well we can show their moves because they both made them so let's do that and it's just rendering that font and we'll display the font after uh you'll see how it works so now otherwise if both players have not gone what we need to do is we need to actually let me just check something for a second is we need to determine if we're going to show locked in meaning the other player actually has gone but we're not going to show their move or if we're going to show waiting which means the other player hasn't gone so to do this we're going to say if game dot p1 went and p equals equal zero so this is saying if uh we have gone and it's our current uh like we are the player we're player one so player one is gone and we are player one what we're going to do is we're gonna say text one equals font dot render move one which is the move we've done which is fine if we see that and then we're gonna say one and color zero zero zero okay l if game dot p2 went and uh is this one it is actually sorry game.p1 went you guys will see this works in a second what we're going to say i'm going to say text 2 equals the same thing now this might be confusing but essentially what this is doing is it's saying if player 1 is gone and we are player 1 we're gonna say uh if i spell render correctly render like that render sorry i got interrupter there okay so if player one is gone and we are player one then we wanna show underneath like your move what our move is otherwise what we wanna show is we wanna show that uh like locked in so we're gonna change this to locked in underneath opponent's move because it means player 1 went but it's not us so it's not our move so that means we want to show it under opponent's move so you'll see how this works we're going to say locked in like that okay all right now we're just going to do else so this actually just stands for if game.p1 hasn't like if they haven't moved yet we're just going to say text 2 equals waiting so we'll say waiting i believe that's correct um actually sorry these all need to be text one my bad okay all right i know this is confusing but we'll go through it after all right so we're gonna actually copy this and we're just going to change everything to two so this is going to be p2 this is going to be one this is going to be 2 it's going to be 2 and it's going to be 2 and this is going to be 2 as well and let me just make sure that i did that correctly i believe i did okay sweet and now we are going to actually show these we're going to split these on the screen we're actually really close to finish guys so to do this we're going to say if p equals equals one so if we're player one what we'll do is say win.blitz and we'll say text 2 and then where we're going to show it we're going to show it at 100 and 350. okay now we'll copy this so ctrl d and we'll blit 1 except instead of 100 we're going to change this to 400 now we're just going to put an else so if we're not player 1 clearly we must be player 0. so we're just going to reverse these player 1 player 2. now the reason we're doing this is because this is going to be where like player 1 and player 2's moves are shown on the screen so we want it to make so that for each of our clients rather than saying like player 1 player 2 and having one of the clients have their move on the right side and one of them have it on the left side we want it to be the same for each client you guys will see how this works when we actually run the thing so let's actually just uh let's add in drawing the buttons so to draw the buttons we could uh we could draw them in this else statement actually that might be better yeah let's do it inside of this this else okay so we're gonna say for vtn in buttons we're just gonna say btn.draw and give it a win and i think that's actually all we need to do and lastly we're just gonna update the display so pygame dot display dot update now assuming i didn't make any critical errors this should actually be working so i know this has been a lot of code and a lot of writing but i think i've kept it to just about an hour now actually and that's actually pretty decent time for creating a game like this so you guys will see how this works out okay so let's try running our server and see if we get any errors first of all okay server waiting for connection server started good sign so far okay clients let's try running a client so i'm going to client oh name p is not defined win game p ah okay so what we're going to do for client this is a really easy fix just change this to player and i might have to change oh yeah up here when i do redraw game window as well you gotta do win um game and player okay so fix that all right client run waiting for player all right good sign let's run another one and would you look at that okay they both launch in now so you saw that waiting for players showed up but as soon as we were ready now both of them are showing up okay so this should be player one this should be player zero or player uh player one player two right okay so let's try this now rock ah ran out of input self.client i received 2048. okay so let's just have a quick look at why this might be ah so i think i might have fine found the issue i'm actually i don't know if this is the issue exactly but we do need to fix this where i do game dot reset inside of server here it actually needs to be reset went uh because that's what i called it inside here reset went so we just gotta make sure we do that okay guys so really silly error here actually um the issue was on the server side here i'm calling play right like game.play and so actually i need to get rid of this i was just printing out the exception so i can see what it was but essentially play doesn't actually exist because i misspelt something on game i misspelt it i misspelled player it should be play so that was the issue i was running into um it just it was very difficult to see because it was just accepting it and not like not printing anything out just continuing to run the server so i couldn't find it but essentially if we run the server and run the two clients now we should have everything working i haven't actually tested it so let's pray if i go paper sweet so it goes paper here we're not getting locked in over here so that might be an issue but let's see if we make something here then since you lost and you won okay so we have a slight issue but it's pretty easy fix let's just go up to uh client just look through we're just probably messing something up in the drawing code here so oh that would make sense well we're not actually end up drawing yeah so this if p equals equals one this just needs to tap back one um one indentation level and now we should have everything actually working fine so let's try this now client client and let's go rock okay so that works but it's not doing the locked in for some reason so let's check this this locked in portion i just did close that server and make sure that this is actually working uh so that needs to be p2 went and well if this one should be working that was what's confusing okay so actually so that one just need to be p2 when game.p2 went um let's try this server and let's go client and let's run it again and go scissors locked in sweet so that's actually working and the game is pretty well finished all we got to do is add a menu screen then we're gonna be done so now let's go scissors this is a scissors scissors that's not correct we gotta fix that as well okay i thought i had everything working guys i really thought so ah okay so i actually i do i do know the issue it was it's pretty straightforward so in main here when we check the uh let's see here the winners where do we check winners if it equals equals one because equals negative one um ah okay so game.winner needs brackets of course it does so we need to add that so obviously just some silly areas guys so servers running right now let's run these clients see if everything is indeed working as as it's supposed to be now okay so let's try this paper blocked in scissors you lost you won yay okay everything's working okay paper paper tie game sweet okay so you guys can obviously mess around with the timing you can see how this is working so the only last thing to do now is watch this if i disconnect it disconnects both of them so what we're going to want to do now if that happens is instead of just completely like exiting the game we're going to want to bring them to a menu screen where they can just click to reconnect and this is a really this actually really easy to do um so what we're going to do is we're just going to define another function i'm going to call this menu underscore screen okay and in here all we're going to do is have a really basic while loop that just checks if you click something and all it's going to do there is click the uh run that main function so we're going to say run equals true we're going to say well run okay and then in here we're going to say for event in high game dot event dot get and then obviously we're going to check if they click exit so if event dot type because it goes pi game dot quit then we will do is just do pi game don't quit run equals false otherwise if they click any key so we'll say if event dot type equals equals pi game dot and we'll just say mouse button down so i should just get it they'll click the mouse button then what we'll do is we'll simply say run equals false and at the bottom of run equals false what we're going to do is we're just going to call main so all this is going to do and we'll call menu underscore screen here so we'll say while true um comma menu screen okay and i'll go through this in a second we'll say while true menu screen okay so we're going to do is in menu screen if they click something we're going to call the main function which is simply going to uh what do you call it do all of this stuff in here and then if they exit out of the main function so if you say like run equals false because they disconnected it'll just rerun the menu screen which means that they'll be prompted to reconnect to new game awesome what we'll do in here is add a clock as well this will say clock equals pi game dot time dot clock give it a tick so clock dot tick 60 uh we'll do we'll just draw something in here we don't need to use the redraw window function uh we'll just do font equals pie game dot font dot sys font in here we'll go comic sans we'll go 60 and then we're just going to render some text we'll say text equals font.render in here we'll simply say click to connect or click to play exclamation point one some nice red text and we can just continually actually we can just window fill um so wind.fill and we'll just fill it with white 0 0 0 or what am i saying gray actually 128 128 and we should just where is win do i define it up here somewhere yes i do so that's sweet winds up there so what we could do is just fill the window run into this while loop put some text on the screen we may actually have to fill this every frame let's get rid of one of those brackets i created so let's fill this every frame actually okay so we'll fill it we will blit this font so let's say wind.blit text and you know what for right now i don't want to deal we'll just do it statically we'll just do like 150 so it's not at the top of the screen actually let's go 100 200 okay and go pi game dot display.update like that then if they click something what should happen is it should break this loop they should be brought to the main thing and yeah that should hopefully be working for us so let's try this client click to play okay a little a little sketchy on the click to play but let's see if we click to play okay waiting for player so this is actually what i wanted so it says waiting for player we're gonna wait for someone else to connect okay boom connected sweet so now we're ready so let's just run a game let's go rock scissors now let's just see what happens if we click x this one goes to the menu screen where it says click to play and it can be what he called play against someone else right and that's exactly what we wanted we may also want to add like a back button to go back but i'll leave that to you guys so guys i'm going to leave the tutorial here if you guys have any questions or run into any bugs or anything please let me know this is by no means like a full complete game there's still obviously a lot of things that could be added to this and i might continue this series later but i think for now that's probably enough i hope that you guys learned how to make an online game i find this stuff really freaking cool and really interesting how you can have like a ton of different clients connecting together and that being said i'll see you guys in another video