Coding Challenge #32.2: Agar.io – Part 2 (Networking with Socket.IO and Node.js)

hello welcome to part 2 of the agario coding challenge in this challenge I am going to attempt to add networking so this is where I last left off obviously this is not the fully formed game agario it will not be by the end of this video but it will give you a lot of the tools and basics if you wanted to recreate it but hopefully you’re watching this to learn about how to do some of this up and invent your own idea anyway so this was what I had before I have this sort of like world that I’m in that I can move around and I can start eating other little dots so but now what I need to do is take this this is a one player version of the game there’s no all the dots are just created randomly I need to make a version where if I launch it one in a browser and you launch it in another browser we’re both seeing each other in each other’s canvas so I’m not going to start from the very very beginning with this because I do already have a playlist and set of tutorials about node and WebSockets so I’m just going to show you the that drill makes this example see how this in this canvas I am drawing a little pattern here I’m gonna refresh that because really what I want to draw is a nice rainbow that’s the worst rainbow ever drawn in the history of time but you can see as I draw here it shows up over there as I draw here you know it shows up on the other screen so what is the what is the schematic what’s the diagram of the things that are happening here there is browser instance one that’s a browser there is browser instance two and in this case both browser instances are on my laptop and that’s how I’m going to demonstrate everything today but certainly the idea here is that I could be playing this here in New York and you could be playing it in London or in Rio or in Tokyo or an Istanbul whatever any city that you could think of around the world I don’t know why those cities popped into my head but they did so um and then there is a server which is written in node J s and the canvas the game itself is written just in using p5.js inside and what’s happening here is there is communication these clients don’t talk to each other they both talk to the server and when one talks to the server I can send my position to the server and the server can then send my position back to the other one so I think this is the way there’s a lot of different ways you could probably implement this I think what I’m going to do is have each client drive around its own world and broadcast its position to the server and then the server will broadcast the positions of all the other clients back to all the other clients so they can draw those other clients in their own window that sounds a little bit like loop-d-loop Dee but hopefully you’ll start to make sense once we start a program okay I’m going to come back over here and this is where I have the code for both of those projects so this is a this is the code for the first agario example and this is the code for that sockets example that does the shared drawing canvas so now what I want to do is I want to grab there’s this public folder right here this public folder is where the client-side code lives so what I’m going to do is I’m going to take the agario folder and I actually I want to leave this I’m going to I’m going to do something a little weird I’m going to do canvas I just want to be able to refer to this code I’m going to put that in a different folder and I’m going to take agario and put that into here so now you’ll notice the note server is running on the port 3000 so if I take localhost 3000 like I don’t see anything but now if I go to canvas you’ll see this is that program and if I then go to agario oh that didn’t show oh because you know I didn’t show up let’s check Oh a gauri oh one I forgot that I called it agario one there it is there so I’m just now my note server is serving both the shared canvas client code and the agario code and that’s useful to me because right now I want to be able to pull pieces of the code from the shared canvas into a gardius oh I can so I can get now have to retype all that socket code from scratch okay so now let’s go back to Adam and what I want to do is uh so I’m not going to adjust the server at the moment this is all the code for the server and again it does the sort of basic stuff of setting up a poor listening for connections spitting something out to the console when somebody connects and then there’s some messaging stuff the massive except is all going to have to change the messaging stuff is what is happening for the shared canvas drawing I’m going to have to change that but what I want to do is I really want to look at the

client code so I want to look at the canvas sketch and I want to look at my agario sketch so I both of these open I have the agario sketch and the canvas sketch and what I want to do is add a socket first I want to add a socket variable and and then I want to connect I want to connect when the sketch starts to the server so this is the basic idea the first thing I want to do is add a web socket to add a web socket to my agario code now I’m missing a piece I believe because now I believe if I were to run that we’re going to see an error message where it’s like IO is not defined so I actually in addition to that I need to make sure I actually access the I so I’m in the wrong place I need to make sure I actually access the socket library as well so I can access the socket library by referencing a link to socket IO in the index.html so I’m also going to take that and go to the Agha Rios index.html file and add a reference to the socket IO library and now you’ll see there we go and if I look back at the server you can see we have a new client so I’m going to restart the server and I’m going to refresh agario and you can see this agario sketch has now connected to the server great okay so now we’ve got step one we’ve got the sketch connecting to the server are you guys with me here are you with me please be with me I’m very happy and that’s really like it’s just an exciting moment just to have it connect so let’s look now but one thing we’ve really got to think about is I’ve got to look at my agario code now this should go away notice how I had this bit of code at the beginning that just makes a whole bunch of blogs but there’s no point in making these random blobs anymore the blobs should only actually exist if they’re actual people playing the game so I am going to get rid of this in addition when I connect I should in addition to just connecting create a new instance of a blob this server is going to have to keep track of a list of all the clients that are currently connected and I think we’re going to have to figure out some way of giving those clients an ID number and there are probably some very clever and sophisticated ways I could come up with assigning IDs I might just to get started use the counter 0 1 2 3 so we’ve got something that’s going on here that I want to just think about here the server needs to keep track of list of connected clients this is data that the server needs to keep track of and that list is essentially going to be mirrored in the client as well and then the server is just going to update the positions continuously so when I go back to the server code right remember now it’s very tricky to keep track of what’s the server with the client especially as they’re both written in JavaScript there’s a nicety to that but I’m going to go back to the server and what I want to do is add a variable so I want a variable at the top and I’m going to call it blobs okay so that is all of the blobs that are currently connected okay and I think it would be useful probably to create a blob object a little unsure about this but let’s let’s do this for right now what if I create I don’t know if I really need a constructor function but let’s just do it just for the sake of argument a blob has an X a blob for the blob has a why and a blob has an ID so I don’t know but in other words that list should always be keeping track of what’s the blobs ID and where is it so I’m wrote a constructor function just in case I need to use it but I’m not entirely sure I do you just yet because just doing this on the fly so when we have a new connection oh the socket gets an ID what a one I have an idea why don’t we use that hein and we might end up using like some kind of like hash table II thing where we look up we look up the client and list based on its ID there’s so many things we could eventually add to this we’ll see but basically at this moment when we have a new client what I want to do is create a blob which is a new blob object with socket ID now I don’t know how I’m going to get the XY position just yet so we’ll figure that out later I’m just going to type in zero zero right now and then I want to say blobs dot push la so

in other words the moment that someone’s connected we then have a new client now I think that actually to the truth of the matter is even better I have now have an idea maybe there the client should in addition to just connecting send a message like start so maybe there should be right because can I get when a user socket ah okay hold on I have to think about this when the server gets a message called Mouse does the do we I AAA yes we should get the particular sock we should still have access to that socket ID so let’s let’s try something let’s say there’s a message called start and the message that comes in is receipt is data is data dot Y and I don’t want to broadcast that back what I want to I want to leave that so what I just want to see is I what I want is for and I want to see a socket sorry I’m figuring this out as I go it’s hard to like talk it through and do it okay this is what I want to do I don’t actually want to create the blob the moment that connected I mean the I want to I want the client to explicitly also send an additional message because here what I want to do is make a new blob object and they have the client send in its XY position so let’s now go to the clients code and here what I want is to send Brooke how do I send something up I need to go back to my previous example which this is how I send something to the server so I’m going to grab this code and go back to my agario sketch and I want to send to the server right the server is going to make ups the server made that I lost a little bit of code there sorry sorry sorry let me get that back socket emit so and I want this to be start so I want the data to be blob X blob dot Y and by the way the blobs all need a size so does the server keep track of the size does the client keep track of the size I guess they both do for right now they’re both going to keep track of it so let’s make a size which is I think blob are I assume which by the way can I just omit the blob it’s going to have all this other stuff in it so I I’m gonna do this right now so there’s definitely a way I can clean this up right essentially what I just made this blob object and then I make this data object which is what I’m sending I can clean that up in a bit but okay so I make the blob object and just to be sure it’s our yep and then I want to send that so let’s see if this works let me go back to the serve code and I realized what I’m going to get I in addition I also want the blob to have an R to keep track of the size and I want to see that here as well just to make sure it’s all coming in and make it with a data dot R so there’s a lot of redundancy here but this should give us the basic idea right if I restart the server and I now refresh the client we have connected I got undefined undefined so I got the ID and I’ve got 64 why did I get undefined for the X’s and Y’s so I’m going to have to debug that where’s my debugging music someday I’ll have it let’s look into this so we’re where are things being set oh I bet you I know why so the blob is actually using vectors so it has a position vector so instead of there when I’m sending the information I actually need to see blah said blob pause X blob pause why so now if I were to refresh this and see you can see now the client connects and it sends its ID it’s X and it’s Y and its size so just to make things kind of have a little variety right now what I want to do is I want the blob to send in a random location and a random size and the size will be smaller between 8 and 24 so

let’s refresh this again and and interestingly there’s a zoom thing happening because everything’s based on having a size of 64 but that’s fine I’m not going to there’s that thing where we’re zooming I’m going to just leave that be for right now so whips I went to the wrong place and we can see that you know it’s very hard to debug in node because now I’m printing out these floating-point things we’re getting all these but you can see the stuff is in different places so this is really good right we both have a we have now a client who connects who gets a unique ID and who broadcasts it’s starting up I’m attached here who broadcast it’s starting X&Y and sighs okay here we go let’s keep moving everybody I’m excited we’re getting we’re getting to this so okay so now here’s the thing every time through draw the blob updates its location so what I think we need to do right now is update the server sense of where I am so what I need to do here is now say in draw I want to do this again but I want to omit an update message so I could probably combine these two but in the beginning a start message means I’m a new blob and now in draw I want to update my X & Y location continuously now latency and scale and all that are going to be complicated questions we’re gonna have to deal with at some point or maybe I won’t deal with it but you will have to deal with it but this is kind of getting started right the chat of someone writes don’t forget to uh don’t forget to delete blobs of disconnected clients which I’ll certainly have to do at some point okay so now what I want to do is in the server I need what sorry I have too many things open I’m going to just go to the server in the server code I need to deal with another message so that’s the start message and this is an update message and I’m going to leave this in here and now instead of instead of instead of creating a new blob and putting it in the array what I want to do is find the blob with that ID now I’m going to do this in a terrible way I’m going to do this in a brute-force method of just looping through the array to find the correct blob later I would love to improve this by using kind of like a dictionary lookup but I’m going to just to have the simplicity of having an array right now I’m going to just leave it this way so which is I’m going to start with a blob called witch which is the one I’m just going to save our blob and then I’m going to loop through the lengths of that array and I’m going to say if blob dot ID oh sorry if a socket dot ID equals blobs index i dot ID right i want to find the blob has the same ID as the socket then I want to say blob equals blobs index I and then what I just want to do is update the location so I want to say blob dot x equals data X blob dot y equals data dot y and blob again I could certainly improve this and just copy the object or make it the same object but for simplicity or say blob R equals data R so this is essentially here now updating that array so what I’m doing now is as the blobs update their location the array keeping track of where all the blobs are gets updated as well okay now I don’t need pause dot X here this is I this is accidental because the way that I programmed it maybe you could do this in a different more better way but I’m using a vector in the client but I’m not using a vector in the server vector object that is okay so let’s see what happens now when I restart the server and I also do this we should see now you can see here the you can see that the location is moving continuously and it’s just I know it’s going down let’s see if I move let’s see if we can I can like move into the client to see it now it’s going back up so we’re not seeing anything move right because it only moves that it’s drawn relative to itself but you can see that this is actually working on some level and I by the way I’m going to have to put some you know constraints around where the blobs can move to okay so we’re good we’ve got now every blob and you can see

now if I were to connect a second one you would see here and if I kill the server for a second we should see I only see one ID so let me try that again when we hit refresh here and we fresh here and there should be hmm and the new client oh okay hold on there’s an error here cannot set property X of undefined so I got some sort of error I must be oh this if I don’t restart the server no we did get two clients so this is straight always just restart the server because the server’s got this persistent a list of clients and if somebody connects and then can’t find that can’t find that in the list we’re going to have a sends an update message so we start the server so you know there’s some cleanup here I need to do but I don’t know why I’m not seeing more than one client message um I am back after some debugging which I realized aha browsers will play tricks on you sometime notice I’m only seeing the updated location of one client it’s not because it’s not working it’s because my browser is actually only showing me one client and the other tab which is hidden has gone to sleep this is a smart thing because why update an animation in a tab you can’t see but if I pull this tab out and make it visible now you can see that I have both of them showing up as they’re both neither is asleep so this is something I just have to keep an eye on as I develop things further so okay so I’m going to put this back I’ll pull it out or just actually close it I’ll pull it out later when I need to so now we need to add a feature there’s a problem here which is that I’m letting these blobs just go infinitely off into a like an infinitely large space and you can see it’s location currently is its location currently is like negative thousand thousand something so I need to put something in the code to constrain them to a fixed space in the screen and the I could be there’s a lot of ways I could do this but I’m going to just do it in a really I’m just going to write a blob constrain and in the blob object I’m going to write a function called this constrain and I’m going to make that blob haha equals constrain blob pause X 0 and width and actually I’m going to say negative with 2 with and I’m going to say Y negative height – height and because it’s 0 0 I think is technically the center the way that I’ve written this if you remember from the previous tutorial so again I could make a bigger world I can make a smaller world I could make it a flexibly sized world depending on how many blobs are there but I’m just going to do this and this should give me a nice now if i refresh this you can’t see me moving but if if I look at this location at some point I remember what the size of the window is I think it’s around 600 you’re going to see that it sort of stopped at negative 600 so this is really useful because as I’m testing it I don’t I want to be able to see things within sort of like a similar world ok so now what I want to do what I want to do now aha so I have everything working I have a server which is receiving information from clients each client having its own blob that’s moving around the screen what I’m not doing is broadcasting back to the the clients where everything else is so oh boy I’m realizing there’s a big complication that’s going to arise in a moment but it’s okay ah we’re gonna we’re gonna we’re going to get through this together being a happy place figuring this out but what I’m at least want to be able to see a step to here I want to see somebody else’s blob up here on my screen I want my blob to appear on their screen ok so here we go let’s figure out how to do that what I need to do is I need the server to broadcast and if you look if you look here I’m trying to think of the best way to do this to start let’s go back to the kid this sorry the server code or have I I think the server code I’ve destroyed it I need to go and grab sorry so what I want to do is what I want to I

just want to create a I want to create mmm I’m trying to think here I want to think that I want to do is create just a heartbeat that every so often the server sends a list of all the current blobs in their location so I am going let’s go back to the canvas example which I sorry I lost my original code let me find it ah let me find it this way sockets server so what I’m looking for is this i/o dot sockets emit sorry I could have this with what I want to do is I’m going to write a function called set interval and what I want to do is have a heartbeat function happen every I’m gonna have a once per second now just to make it really slow to update and I want this function heartbeat to emit a heartbeat I call it a heartbeat I think that’s a common word in networking like it’s like your heart is continuously beating at regular intervals this is something that the server’s just going to do at regular intervals and what’s it going to do it’s going to send out the full list of blobs and actually right now it’s just going to send out hello so I just want to see and I I just want to see a message I want to see that I can get the client to receive a message from the server every second okay so let’s see how that works let me go back to the client code and a client code I need to go back into the canvas and see icon I need to add this this on method I want to do something when I receive that heartbeat so I’m going to bring that in and I’m going to put it in set up and when I receive the heartbeat I just want to say console dot log data I just want to see that message come in okay so now I’ve added a heartbeat to the server and a heartbeat to the client so let’s run this again let’s run the client and we should see hello hello hello hello hello servers setting up now let’s change the server to do something else instead of sending hello I’ve got to go back to the server let’s actually send that array let’s just put the array in there let’s see what happens if we just put the array in there we might have to stringify it I’m not sure but let’s just put the array in there and see what we get oh I was a loud noise okay so I’m going to restart the server and I’m going to refresh the client an object object let’s look in object there it is it’s an array with so it’s actually sending it as an object which is terrific you can see the ID are so I’m actually getting all this information in the client now bear with me here let’s connect to second client and a third client and a fourth client and let’s look at what that heartbeat looks like now I got to go look look at this an array of four things there we go all four things right there so what is it that we want to do all I’ve got to do now is loop through those four things and display them on the screen the server sending me here’s where everything is here’s where everything is here’s where everything is oh this is wonderful so let’s go ahead and do that so I’m going to add to the client code where’s my client code so many different things here it is I’m in draw okay so here so I need an array oh that array blobs I already have it I’m going to say blobs equals data does that was an array and then what I’m going to do is they’re going to say for VAR I equals zero I is less than oh I have that they’re so funny that I have this year already and I was going through it backwards but they’re not actually blob objects boy I’m just going to draw just to see that through the hair I’m just going to draw an ellipse blobs index IX blobs index I dot y blobs index i dot R times two and I’m going to draw it I’m going to make it a different color and I’m going to say let’s just make it like a blue or something so we see it as a different color so let’s just see how that works

there we go look those are the other blobs and I can kind of walk around and try to find them those are from the other clients and I could go to the other client and I could try to find probably presumably I have to refresh I could find the other blocks now one thing I might like to do is actually display the ID is that’s going to kind of kind of help things I don’t know what’s going on there new blobs are connecting continuously let’s just see blobs dot length whoops there we go yeah I don’t know why I have so many so I there’s some debugging that I’ve got to do here seven no it’s right I guess I have seven tabs open do I books do I have seven tabs open a geeky track you know what though the server hasn’t been restarted and I’ve been doing all sorts of crazy stuff so in these kind of cases it’s generally good to start over so let’s just do two blobs and see if things are working so I’m gonna whoops and I went to the wrong server the wrong project 3000 here we go okay so back in I’m drawing myself and I’m drawing myself only once per second so as I move around it sort of looks like it’s like I’m still drawing myself in a previous historical location so that I’m going to fix as I stop drawing myself which I need to do so one thing I want to do is I want to draw the blobs with their ID so let me just for a second see if I can make that happen really kind of quickly you know like a not so awful I’m going to say fill 255 text blobs index ID and then I want to say blobs Dex I dot X mobs index I dot y plus R plump blobs in index I dot R times three let’s have it appear below and let’s say text-align:center am I getting the ID yeah okay we’ll go away that’s not so let’s make the ID a lot smaller I think probably the window yeah text size 12 and the times three was unnecessary okay so I want to see let’s make this six well what’s going on with text size okay that’s kind of what I wanted to do so I just want to be able to see quickly the ID below each of the blocks okay we’re getting somewhere we’re getting close now here’s the thing I want to not draw myself there’s going to be a third part to this clearly we’re getting pretty close I’m gonna release this code and you guys can kind of get further on your own and I’ll come back and do the third part at some point but the couple things I want to fix here number one is I wanted I want to know my own ID and not draw myself so I need to have in this particular sketch my own ID and I would like the I would like to send from the server a message just back to myself now so when I send this first start I want in server – I want the server to send a message back with the clients ID like the client needs to know its ID so the question is how do we in how do we use node WebSockets to send a message only to this particular client and it’s probably something like socket dot omit or something but I’m just going to look this up set node sockets send message to want specific clients so here so so how do we do this you have to grab the client ID and we can just say i/o dot client session ID

dot sin let’s see if that works so let’s see if this works like what if I then say this and so I want to say socket I D I wonder if the client has this built in somehow does the client have this built in somehow let’s look at this oh look there’s the ID look the client already knows its own ID isn’t that wonderful so I don’t need to send it back the client knows its own ID now why is the client have to have it as with alpha without the extra numb / in number but that’s fine we can work that out so what I want to do here now so I don’t need this what I want to do in the client is I want to when I’m drawing them I want to only draw them if the ID is not my own ID so I want to say as long as blobs index ID ID does not equal socket ID but the problem with that is blobs ID has a couple extra characters at the beginning so I’ll just do this I can just chop those off I think with substring substring is a method that will give me a part of a string and if I go back to the sketch and look please don’t move around you can see that there are there are just two extra characters 0 1 so I want the substring to start at 2 so I want the substring to start at 2 , and let’s just let’s make this simpler let’s save our ID equals blobs index I’d ID and then I can say ID dot substring to 2 the length of the string so I want to make a substring from the second character all the way to the end and as long as that’s not the case then I can draw that particular blob okay so let’s see here so we should be good in that well there’s a whole lot above now we can see that I can find other blobs of varying sizes if I kind of poke the screen but I am NOT drawing myself so we’re in pretty good shape here let’s let’s change a couple things first of all let’s restart the server I think that we can now in the server do away with this console dot log that’s happening over and over again as everyone updates itself and we can what we can do is now really test out two particular clients so to do this what I want to do is kind of divide my I’m going to get rid of the I want to divide my win screen in half here and I’m going to just go to I have two windows open that aren’t connected yet to the server then I want to run the server connect this one to sorry agario one and you can see there’s a client connected then I want to connect this one to agario one and there’s another client connected so we can see what their locations starting locations are and I should be able to now move around and try to find it anybody anybody where are you other blob okay okay I am back okay so I’m going to just console.log the blobs x and y position so I can take a look at that and the other thing I was going to do here is only say if mouse is pressed then update the location so I’m actually not going to move a particular blob unless unless you click the mouse so what I want to do is I need to find terminal again this is going to help me debug so I’m going to kill the server I’m going to hit refresh which will make it so that it doesn’t actually connect

and then I’m going to restart the server I’m going to start one blob and it’s saying undefined sold I need to fix that blob pause X love dot pause dot Y so let me refresh again you can see okay so and that’s now showing both of them so hold on I’m going to restart the server and refresh this okay so you can see here this particular blob has shown up at this location 150 comma 24 and let me make this a little bigger there we go and now I’m going to go to the other blob I’m going to start a new one whoops and you can see there it is so now I want to move this blob a little bit whoops and let me see if I and that worked there we go and the thing is it’s only updating it’s only updating once a second and so I can move closer and you can see okay so let me fix that and so this is totally working by the way but let’s kill the server again I’m going to make this look a little bit better so I should I don’t know what’s reasonable but I’m gonna have the server have its heartbeat 30 frames per second is a and there’s a thousand milliseconds in one second so let’s say let’s have the heartbeat happen every like 33 milliseconds let’s see if it can handle that so I’m going to restart the server and I’m hit refresh here and I’m going to take that out and I’ma hit refresh here whoops hit refresh here and we should see now as I move and let’s get a third one going let’s get uh OOP ah this is I’m gonna get a third one going and one more come on you can do it Oh Gauri oh there we go so we can see here if I were to move around they’re all responding to each other we’ve got a multi player kind of beginnings of a multi player agario here so okay everybody this is the end of part 2 I don’t know how long this video was or if it was it all understandable or useful at the very least you sort of saw how difficult this is and I will release the code for what I’ve got so far so there’s a big missing piece here which is that I’ve got a check intersection and figure out what to do actually add the game mechanics where you when they intersect the bigger one eats the smaller one just what you’re gain the smaller ones game is over maybe you can start again there’s a lot more steps to add to this but this I think is going to get you a little bit further as you can see the sort of basic mechanics of having a server keep track of a list of everyone connected have the client implement their own motion physics update their location to the server and if the server send those new locations back to the clients so that they update so you know there’s a question of you know how do you deploy this what would happen if you suddenly had a hundred thousand people playing this all at once there’s no dude WebSockets going to support that but you can sort of see the basic ideas of how you can have this more sophisticated networking multiplayer networking working so thanks for watching this particular video this was part 2 when at some point I will release a part three which I do a few more steps although it might be a while before I get to that thanks again