 Hello there, welcome back to another episode of the multiplayer scaleable multiplayer game design, open ship, multi scaleable, multi scaler, yes it's been a long time and many things have changed the red hat live streams and so I couldn't even find an intro tool video to play so I apologize that we're we're just getting in there hard and fast without without any warning but you know we'll do it live so whatever so what are we going to talk about today Roddy? So basically how where we left off and I guess where we are now right so when we left off we had a client in a server and they talked to each other and we can do a little bit of small gameplay with a couple of ships bouncing off each other. Did we even have that much? I don't know I think no yeah we did with the web plant yeah with the web plant right and that's and then we kind of we looked at our our rate of development then we were saying well you know how can we bring in more of a community and we looked at what I brought on board which was like an early native C++ client that was like explicitly dependency injected and it used the C proton client and that actually was an update from like an earlier version and so basically we said like hey this is kind of hard to work with for some people who are used to maybe doing web development or doing c-sharp development and how could we move this in a way that's more standard right so we did move to AMQP because it's an open standard protocol and a while ago a few of us had done this thing called PodEscape and we used this open source game development tool called Godot and we had a really good experience with it. We don't have that IO site for PodEscape or is that just on the Red Hat Arcade? It's just on the Red Hat Arcade now the podescape.io is right here right and so we developed this over the course of a couple of months and it's how did you develop it? We used Godot and it was a 2D game and a bunch of us collaborated on it through GitHub and so we're doing a very similar thing now where we're doing a 2D game and we're collaborating it on it through GitHub except we're adding in the multiplayer aspect and we want to deploy it on OpenShift. Now this one is deployed on OpenShift but essentially what happens we do so one of the things that's useful about Godot for example is that Godot can do wasm or WebAssembly builds so for PodEscape we chose to write it in c-sharp and that uses a model underneath the hood and then you compile that to WebAssembly you take that package of WebAssembly and you host that in a container image that's running a web server you take that container image with the web server and our content and you put it on OpenShift and you set up your networking appropriately and here you go you have PodEscape at the Red Hat Arcade right so so we've kind of done like some of this similar work but now we were like well what could using these tools bring to us for what we want to do today and so using this game development environment we are hoping will allow us to speed up our rate of attracting people because there's a multiple different ways you can use the tool people are familiar with it it's established there's loads of tutorials instead of looking at my original like you know C++ server code and kind of going hmm I wonder how does this work yeah up in Godot and look at it in the GUI and go I'm gonna poke and click a bunch of stuff and see what happens and you know obviously any of us who are programmers can relate to doing stuff see what happens repeat and rinse and repeat right so so we're hoping that in using this tool we can lean on like the whole entity component architecture and bring in our like our messaging subsystem and at the end of the day we'll have a community who understands the tool who might want to participate and we'll have maybe something we can contribute to the community via our work with messaging in relation to Godot while at the same or anything else that we do right whether that's so or data grid or you know a pile of good stuff here where there could be synergy and there isn't yet today and I think it could be a win-win even though you know you think scalable multiplayer and you might think 3d shooter and then you might think you know oh well that has to be written from scratch to be as fast as it needs to be right but if you look at the time we're looking at well part of it too but even starting with the type of game we're starting with here it's a 2d space shooter that's not necessarily twitch-based and in thematically is more like start control or something where you may have some keyboard control but when you hit a missile launch you know the missile goes off and it's not it's not like you know using rocket launchers to propel yourself off the side of a mountain like rocket jump yeah exactly right you know we're not thinking along the same lines right so you know it gives us a place to start and who knows in the future we may we may get to the point where we've honed everything well enough that we can do a first-person shooter but really it's not necessarily the focus of what we're trying to do here that's realize this diagrams not correct anymore because it's got the phaser clamp which we switched away from right and so so essentially even though we've switched to Kedou and we switched using C-sharp one of the interesting things about what we had chosen to do in the beginning was that we chose so way back when there was a C++ server and there was a C-sharp server in Unity talking JMS over a messaging subsystem oh yeah that was your like very first part of that yeah like way way back right and then we had a C++ server talking open standard AMQP to a web client in JavaScript right and so even though we had a JavaScript client we had the server still running and we had the same messaging going on because the messages were defined in protobuf and today we evolved again and one of the things that stayed the same is that the messaging is stayed the same we're still using AMQP we still have messages formatted in protocol buffers so those protocols haven't changed at all and yet we still we now have a server in C-sharp on top of Kedou and we have a client in C-sharp on top of Kedou using an AMQP net client which is a different client written in C-sharp but still talks industry standard AMQP 1.0 ISO standard 1994 64,014 or whatever it happens to be and protocol buffers right so so even though we've had this evolution of tools and technologies now I want to look up we still have we still have the same network communication going on which I think talks to the flexibility of of the messaging subsystem as the piece in the middle that allows communication to take place between a client or many clients and in this case a server or what in the future we hope to be a scale out a bowl server so that we can have a fleet of servers which handle of clients and we have a messaging subsystem in the middle yeah all right so with that background we'll take a look at our server sorry let me close this editor and this is the server so I'm doing all my development on Fedora I'm using VS code with C-sharp hooked into the editor I just followed the tutorial for doing C-sharp with VS code on the Godot website and it basically just worked a little bit of nuance and a couple of gotchas with some of the like where did I have to get net and new get and some of these things but for the for the most part it was it was very trivial and so the initial thing to do was basically we took that old server code and I just started like working backwards in reverse engineering it into Godot and so it was like all right well when the server boots it needs to talk to the messaging broker and I was like all right well is there a C-sharp client for AMQP and sure enough there is this AMQP framing types what have you let me pull up this CS prods here because that's actually going to show us so there is this AMQP net light library which provides AMQP framing and types in AMQP which allows us to set up connections and do other things and so basically when the server first boots it initializes the connection to the AMQP server creates a connection factory and then sets up different queues and targets and senders and receivers for the things that we're doing and ultimately it's it tells it to sort of respond to when commands come in and so on and so forth and so that was sort of the step one I was like all right can I can I even make that work and sure enough it did I'm gonna have to undo this change if I want this to not explode sorry I was in the process of developing some alternative sewer config file so that we can shove this in containers but anyway so pretty simply the game oh gosh where's the process ready ready okay so I found some random logging library which was pretty awesome which made it easy for us to do logging stuff and then we load a config file for the logger and then we start spitting out log messages we define this message interface which makes an easy way to like call the functions of sending and receiving and doing things load our config file set up some stuff and then that's it for the ready and then in the process where is process do we have an actual process come on process so process is the normal frame thing that Godot does and so we have a UI that we're rendering because we're using it for debug purposes but you could just as easily not render anything for a game server but effectively every frame we do this process and so what do we do we we find some items in the screen to update them and then we look for if somebody is sitting at the debug console and pressing buttons to control one of the ships in the game we do this process player joins which has to do with when messages come in about players joining or leaving and then we send updates to all the attached clients and then this has to do with the the debug UI tree kind of thing and so on the surface like this is really pretty simple Godot stuff right it's all normal seen things right so what is process player joins do so if we dig in here a little bit come on really that's very bizarre why are you doing this go to definition there we go so there's the C sharp Q object and it says basically if the count is bigger than zero DQ stuff out of the Q we're using proto buff I think Robbie mentioned that earlier as a binary transport mechanism to send via the messages over a MQP and unsurprisingly there is a search there is a protobuf net implementation and so we have all of our protobuf files in dot proto format and then when you use protobuf net you can actually compile them into native C sharp code and so you get this crazy insane looking pile of C sharp that nobody expects you to actually know how to work with because all you're ever going to do is refer to things in the protobuf and so in the case of the game server we have this particular message that was object this security command buffer that was sitting in this Q we instantiate a player if we look at what instantiate player does we have this sector map and blah blah blah we're not going to go through any of the super low-level details yet but for the most part like this is very simple C sharp scripting like I am I wrote 99% of this maybe 90% I don't know there's probably a way to ask it and get how to who wrote all the code but I'm not a programmer and I was really struggling to Roddy's point with the C plus plus implementation of the old server because like none of the interfaces were documented and it was like wasn't clear what was going on and there was like internal messaging and external messaging this stuff is like it's all basically vanilla Godot C sharp and a little bit of like rudimentary scripting like oh like what what do I have to do to interact with arrays in C sharp or or whatever right but effectively and I probably should build a diagram for this if we look at what happens in the AMQP library so a command comes in from somewhere right so when this when this receiver receives a command message it calls this command received function and if we go to the definition of this command receive function we accept the message which tells the broker like hey you know we actually got this you can you can delete it or do whatever it is you want to do with it based on your configuration and then we decode the binary stuff into a command buffer which is just a type of protobuf and then we call this process game event within the actual main server scene if you will so if we go to the definition of process game event we have a couple different types of messages there are security messages which is when players leave or join and then there's input messages which is like the player is shooting or the player is moving and so we have these different process methods for moving and shooting and for security events so we'll go to security event first and so again this is just a bunch of like very rudimentary scripting right like oh if the message type was a join message in queue a player join or if it was a leave message right now we actually don't process leave messages nothing happens to the player so I should there's probably be a to-do there buffer this because it collides with sending game updates I think actually this is fixed by this in queue this to-do statement yeah anyway and then we've got the process move command so if we go to the definition of move again it decodes the binary stuff and then it figures out like okay which player are we actually moving based on the UID that was attached to the message we calculate the what buttons they were pressing so the game client has to tell us like what their x movement is and what their y movement is this is basically true false we're doing very hacky simple space movement and then we put a movement item which is just this thrust vector into the players into the queue for this particular player so if we look at this oops definitely don't need to know about the queue function where's the definition of this movement queue and so here we've got this movement queue which is a C sharp queue and if we look at where it actually gets used we come down here in the physics process for the player scene again this is like all vanilla Godot stuff this is not a how to use Godot stream this is more of a what we did with Godot stream but hey look here's this explains kind of a little bit how we did our how we did our physics air quotes physics it's not really physics it's basically like hacky asteroid-ish movement so what do we do we figure out where the ship is we fig you know find all these labels that we want to update which is related to the debug mode of the server we update the labels and then basically we say hey if there's anything in the queue for for movement let's go ahead and process it so we if the movement was in the y direction we lerp their velocity if the movement was in the x direction we do something else and then basically we do the Godot's move and collide function based on which way they're moving and then we clamp them inside of like this big spherical well circular star field or whatever so let's actually get into like watching the debugging thing and see what we can see so one of the key prerequisites is we actually need the message broker to be running somewhere and so I'm basically just running the Artemis broker from upstream I downloaded the zip file and then you know did a couple things to get it to run and so this sets up a server with sorry a broker with all the basics but as you can see sorry even if you didn't do anything if you just ran it after unzipping it created a broker and then ran it you'd get a an AMQP acceptor open on your local machine so if you're doing local development like grab the zip unzip it even before touching containers and you'd be good to go yeah so download Apache Artemis and I'm just using Apache Artemis from the zip file but we've got it set up so that it does listen for AMQP 5672 is the default port I am not using ngrok right now so let's go to the server here and look at the I gotta change the config file name because oops I rebooted my computer so I have to do CTL system gosh so for whatever reason I have a keychron Bluetooth keyboard and the function keys like they don't they don't work right because there's some weird Mac Linux USB I don't even know so I literally have like a system descript that makes the function keys work because otherwise they just want to like they're they're stuck in alternate mode so like if I want to use f5 to refresh the browser it tries to make the screen brightness change so I gotta fix it anyway well what did I say I needed to do oh rename the config file let's see so I think this will actually build and run okay so let's actually look at the config file localhost 5672 that's correct we've got a couple of other things for the game itself like these these are kind of sensible defaults if you will and then within VS code I'm gonna play in the editor and when I do this it's gonna build the C sharp and you'll notice that we get a bunch of errors these are actually oops I thought we got a bunch of errors yeah so we get all these weird errors this is apparently normal output based on the way the protobuf.net compiler generates C sharp like even though it says errors they still work but anyway so what we've got here is a bunch of debug output from the game server so it loaded the logging configuration it initialized the mpq a mqp connection configured itself and says hey I've finished initializing the a mqp connection so if I switch to this thing you can see this is the game server debug console running and so this is an area that shows like a list of the players that are known to the game and then we can just create a player ID and hit the join button and then we get an actual player object happening if I switch to the here you'll see that we added a player instance like here's the when I press the join button we logged that we were sending a message and then the server was like oh I got a join message for this ABC player and then later the server is like cool I'm adding an instance of this player somewhere okay cool and so this is a player instance and it's accepting the keyboard input if you will so I can turn them left and right I can increase their velocity I can decrease their velocity down to zero and I think control is fire boom so there's the space missile off it goes yeah one thing you notice the camera in the server there is locked the center on the ship yes very true it's always in the center it is actually really moving relatively speaking yeah so if I join another player we'll get this BDE player over here and you can see the screen switched and if I click in the debug on ABC it'll zoom me back in and I did add some zoomy stuff and if you look at the code repo which is under Red Hat Game Dev in the server right SRT Godot server in the Red Hat Game Dev organization I try if I wherever I copied and pasted from Stack Overflow I tried to link to the original the original example that I had found so if we look for the zoom you know what I did not link to the tutorial that I used for the zoom now I feel bad and I have to find whatever the zoom was yeah put okay so back to the server so I've got another player and if I move this player we'll see that they get close that was weird I don't know what just happened oh god oh I see what happened oh no I've seriously broken the game I guess I never tried well no so what's happening is when I press the down button it's capturing down the down button in the UI selector and it's not actually doing the right thing so I'll have to figure out how to fix that and make this guy not capture keyboard input yeah but anyway and so if I shoot and the missile hits the other player really so close so far this game is fun already like I haven't even it's oh man you know what this reminds me of Roddy it reminds me of quap do you yeah so qwop so for those of you who aren't familiar with quap I'll pull it up on Wikipedia so it was a game where you had to make somebody run but it used the qw o and p keys on the keyboard and map them to like the muscles of the of the runner but like it did not make sense and it was nearly impossible and just maddeningly frustrating right and so it's funny like it's not this even remotely but yeah just like that that minor miss felt very quappy in nature so anyway so this player shot the space missile hit the other player you can see the hit points went down to 75 I shoot again they go down again and so on and so forth I don't have a way to actually remove players right now because very very early hacky build stuff going on here but cool alright so I'm going to minimize this and then what I'm going to do is switch to the game client and it is entirely possible that this will explode but the game client is basically just the game server in reverse right now so it and it's also a more well organized repository thanks for again man that's we appreciate your support so we still have this server connection thing which is doing the amqp it's got a little bit more robust error handling and explosion of on failure kind of things if it doesn't work out right so if I look at the client config let's see so this is local host five six seven two and if I why are you showing me this oh right yeah I fix oh you know what I think I had to fix the fonts right I don't know if that got uploaded anyway whatever so if I launch this game client it's going to do a build I think it's going to try to do a build you get the same errors from the protobuf mqp library thing it's fine it's not the end of the world and then eventually it pops up the game client great and so thanks to Kaleek Ray on our team he made these cool graphics for the space rings things what is called sign of the captain we'll just call it captain and then we'll hit the join game button and hopefully something will happen oh I can't use I can't click the mouse tab and then space yes and it's broken I think Roddy this is the problem that you had fixed yes with the UID versus the player name being used as the identity yeah but back to the game server we see that there's this new player captain and they're off in their own sector way far away because that's how we implemented the game we only allow two players in a sector to start and so there's this whole hex bob based thing going on you have those diagram that little presentation thingy you drew oh yeah really that was really a good visual to explain what the end goal is and why that behavior occurs that's in my personal you get to a safety yeah can I get to it safe I think I can I think I can my computer might explode but I'm pretty sure that I can get to it SRT so for those of you who are familiar with old hex based games or like tile games if you remember even before hexes when when sieve was like square tiles Roddy can you still hear me I can hear you because my computer is in full meltdown mode I load average now 15 16 yeah that's the one I was thinking of I think yeah hold on let me do this close to windows yeah baby okay so I made this presentation that sort of describes how we're used doing hex stuff oh and before I do this this is definitely red blob games yeah that's definitely the go-to place for hex tiling so this red blob games hexagonal grids like holy crap thank you so much sir for putting this out there because it is amazing so it goes into excruciating detail on how hex is worth and hex has little active demos like yeah and like JavaScript like stuff and math and all these other things and so anyway so this is super cool right like absolutely no questions asked like amazing that this exists but then even better there is this guide to implementing your own library with a C sharp implementation where no where where is it there's the C sharp I pulled I could have sworn I pulled it from this site where ah here we go code from this page in C sharp here is a C sharp file with all of the hex code so I this is again copying and pasting from Stack Overflow I wrote next to nothing I think I made like extraordinarily minor name or label changes in this file like but basically I just I just ate this file right right off so so we're doing hex stuff but we're doing it in a little different way the ships don't like they just travel through space but what we did was we said okay there's gonna be this like play area with hexes inside of it and the hex will be used to determine where players get instantiated so now we're into now we're getting into sort of game design cloud abide I'm not I'm not sure oh scale up my workstations I will do my best to make my fonts bigger I apologize so from a hex perspective we're using the hex to locate where players are gonna get instantiated so when the first two players start the game there's this sphere well technically it's a circle and that's the clamped play area that I was referring to earlier and then we'll dump the first two players in here and then when more players come in we use the red blob games tutorial for oh gosh of course it's the wrong browser window oh it's this browser window that's annoying sorry hey you'd think I'd streamed once before in my life limitation of hex grid rotation notes map fractional where was the sorry I need to figure out which one it was that I used there's a very specific thing was navigation let me ready yeah yeah mayor and so like why are looking for that there one of the things that this leads to like a little further down the line is like area of interest calculation so one of our goals of the design is to be able to scale this out across a larger open shift cluster by spawning pods of new game servers which will then dynamically balance the load of the players as they're playing right and so in order to do that having this tile layout and all these calculations up front will further down the line allow us to hopefully use some algorithms that are already known for area of interest that people have developed over years for massively multiplayer games among different you know numbers of instances of the server and so that we can scale these out evenly at least that's the plan and that's the that's the experimental design goal that we're going for when you run out of CPU scale up your systems oh yeah that's very true you could vertically scale but it's hard to do that while players are playing because usually that involves taking down the server but yes the goal here it brings up a good point and maybe something to refresh what we're talking about the goal here is essentially we want to be able to horizontally scale because you know theoretically that's easy right especially in the cloud you know and with a container platform like OpenShift it's it's you know could be made to be automatic even the difficult part to Roddy's point is like figuring out the logic of transferring the area of interest that a server is maintaining you know and that state to another one but that brings up like we were planning on using some kind of data grid or data cache for for stateful information blah blah anyway so once I had gotten to where's that slide presentation once I had gotten to this and I was like okay cool ignore the hex for a second like I've got two players okay where do I put the third player so the first thing I did was like horrible like random you know sort of like literal random number generation to plot players which which immediately gets to be terrible and then I was like alright how how can we more meaningfully distribute players and so then I was like looking up like distribution stuff and then I ended up finding like plus on distribution you know see like in C sharp to like try and like figure out how to place things and I was just like this this is awful and it's it's not necessarily gonna always give you like two players kind of in a reasonable space and I don't remember how I ended up accidentally finding or stumbling onto the idea of using hexes but I was like okay well we've got this concept of rings for the game as like a game design element how how could we distribute players in there and I was like alright well we want to distribute players around these rings somehow hexes I was like well what if what if we just like traversed around the ring and just dumped two players in each of these things and we'll call them sectors because we had had conceptually this idea of sectors that we had talked about and so basically between all the streams we had done and all the all the BS like back and forth and all these other things I was like well what if we like put sectors around the ring and they just keep growing out or whatever and so then I've stumbled upon this idea of okay so we've got these hexes and the first one is the center hex in a ring and then once you get more players you do this like ring traversal is something on a ring but you kind of like turn your head sideways and do it as like well let me just traverse the ring and if there's not players in that sector in that hex it's actually this this one traversing the rings one by running a spiral pattern we're doing this so you go here and it's like okay well there's two players here well let me get bigger okay there's nobody here I'll put two players hey there's two players here okay let me put them here and we sort of traverse around so what I settled on was okay we'll start here we'll put two more players in and then the new pair will end up in this next ring but we like kind of shift the center of the sphere to keep like them from just flying completely apart from one another this is like in Street Fighter or Star Control where there's like there's sort of a big play area but there's a defined boundary that you can't go outside and maybe we'll get to a point where if like if you try to go outside it gets destroyed I don't know whatever but the point is the next two players go into a sector on the ring and then the new pair gets deposited into the next sector on the ring and so on and so forth and so later you get a third pair without piling and then like much later into the game you can have a situation where players have moved around and ended up in other sectors and so in this case like this one sector is actually empty so if we have a player join in this game state we would start in the center and I know it doesn't look centered because of the way the ring has grown but trust me this is the center one with just the play area clamped off to the side you would go oh there's two players here I can't go in zero all right let me go to one hey there's nobody here this is where I'll put the player even though we've got these other players here I think that's the okay and then sort of really late in the game you've got sort of players randomly distributed because they've moved around and so you would start in the center and you would say oh hey we've got this note there's only one player here we could put the first player here and then you'd sort of traverse around and be like oh okay now we can put a player here so now if we go to actual sort of code land server good server and we dig into the server code I legitimately I swear to you I had a piece of paper and a pencil and I was doing okay so here you go traverse sectors based on the function from red blob games I had to take this pseudocode and some of the other like implementation functions and like loosely translate them to C sharp and then I was sitting there with a pen and paper like doing the math to make sure that it worked because it like it just I couldn't believe that it worked and then I actually was having some problems where I had I had implemented it badly and I don't remember what it was it was like I was missing a less than and I had less than equals instead of less than or something it was like totally behaving badly it's usually something small oh it was something tiny it was behaving really badly but basically after a bunch of writing things with pencil and paper and figuring out that no this this stuff really works we got to this code so essentially I'm actually gonna try to walk you through this a little bit more explicitly so we process the player joins then we instantiate a player and so when we go to instantiate player we update the sector map and so this is says update the map in preparation for traversing the ring so basically every time a player joins we nuke our picture or our view of the sector map which is just an array well sorry it's a dictionary of sectors and how many players are in them and so we basically go across each of the players that we know about and then we calculate using a function from red blob what sector that player is in based on their x y coordinates and then we say okay if the sector map contains an entry for that sector add one to it and if it doesn't then this is the first time we've seen it so just make it one and so basically we iterate all over all the players and we build the sector map of all the players that we know about which tells us how many players are in each sector and so then we go all right we start with the center we instantiate this new player object and we set their values this is just like basic initialization stuff we add this particular player into the known list of player objects and then now we start traversing the ring to find out where we're actually going to put this player so if we have more than two players that means we need to be doing ring stuff so we're outside of that first initial central sector if the current known radius is zero we have to make it bigger than one or bigger than zero we got to make it bigger it's possible that for somehow we ended up with no players in sector zero like late game so let's check if it has enough players just for funsies if it does have less than two players we actually don't have to do anything because we default to the current sector being zero i realize that's probably bad weird code but whatever um otherwise if we're not doing something with sector zero and we have a ring radius then we actually start to do our traversal and that traversal will tell us what sector we're actually going to dump a player into so if we look at this traverse sectors this is the red blob stuff so we iterate with the eyes and the jays um and basically we do something dumb we say okay we look at every single sector that we know of and look up how many players it is if it has less than two players then we return that as the one that we want um otherwise we go to the neighbor and then whatever and then i forget what this one does oh and then if somehow we got to the very end of it we make the ring if we if we got through all the known sectors in all the known rings we make the ring radius bigger and then we go to the next sector on that ring and we say that's the one that we're going to put the player into so we've traversed everybody and we set the new starfield radius to the current size of a sector which for simplicity we're just using a thousand pixels which i know is weird like at some point we'll have to do some sort of real world air quotes real world math to decide like what uh uh how big is a ship and and how big is a reasonable size for a sector and so on and so forth um we set the center to oh we look for the center in pixels of the sector that we want to put the player in and then we badly randomized the start position within that sector and then we take the new player that we were instantiating and we set their x and y coordinates to be this badly randomized thing and then we actually finally add them to the scene this is good stuff and then we tell all the other game clients that a player has joined right so this is a specific type of game buffer which is a game event which is the create buffer uh let me pass that in i apparently have a chat window open somewhere that i need to close there we go yeah and it was interesting earlier like when you ran the client and we saw that there was like that little pocket of two ships and then further away there was that one ship right and we can see basically that this is this hex tiling in action right yep and so now if i add brad and join brad badly randomized brad is like legit on top of cappin but you can see their sector right negative one one zero negative one one zero if i click on abc this is sector zero sector zero right and so now if i add susan susan is in zero one negative one if i zoom out we can see brad and captain over here um and then if i zoom i can't zoom out any further but um we would see abc and bde kind of up in this neck of the woods right so this is the sector stuff in action if i add um jeff not particularly random so gotta work on the random function but uh you know at least we get two players in the sector whenever we join players so let's go back i'm gonna kill the server and i'm gonna kill the client did you did we pr that change to the server i don't or sorry to the client the one that you made or did you just point out in the code i think i just pointed it out i had to change here locally can you i can take a look and see if i can find it here yeah so i'll i'll look i'll look in the code where it actually got changed so i think it was in the server connection where and there was a comment that kind of pointed out that it wasn't using the uuid and it was switching to use the player name right see although i think it must have been in there though because if you wouldn't have gotten all the different players in well the i didn't try to move them which is what caused the explosion but because the uuid is different the client was drawing what it knew about yes but it didn't know about it yeah anyway the client didn't know what to draw in the right way i'm pretty sure that when you change that it fixes the client um to where no it's in the play it's in the game where we actually join where we send a join message so now we're doing yeah join game as player sending join with uuid ye i think so this is commented out yeah so that should not be the player name that should be the server connection that uuid and the thing is is that that's a little bit misleading in that the uuid that's there is not the uuid of the server connection but is the uuid of the current player stored in the server connection object which is why when you put it back to make it work it looks odd it's a structural deficiency yeah i don't want to get too deep into why that is because i don't even understand it right now but whatever we'll give it a try and see if it works so what that was definitely the change okay so this is the server let's restart the server is running okay cool and then we want to restart the client can't tell how many people are watching right now five people are watching wow thanks five people for watching definitely ask questions if you have questions this is like a combination of hackish gado stuff c sharp and uh game design all right capn invisible doesn't know what sector we're in it doesn't know where we are we're definitely connected to the server you know i'm gonna just for giggles i'm gonna try killing the server and restarting it for the broker there's a lot of like garbage cleanupy stuff that we probably need to be doing that we're not doing right now all right start the server i could have sworn can you check the public repo ready and see if um the changes in there actually i suppose i could just do that myself yeah i'll just pop it up here hit remote get pull origin main oh definitely there's changes yeah discard changes to client config discard changes to game dot cs get pull origin main whoa yeah okay lots of things have changed recently so that could definitely be what's going on okay local host all right um game dot cs ship instance u id equals u u id create ship for u u id okay whatever let's see if it works so we got a server with nothing we've got one consumer one connection waiting for the game to finish building and come up unless it exploded nope still building okay game engine here we go what's the call sign of the captain we see another connection got happened right so the the client has joined so if we do happen and we join the game fingers crossed well we got the player the client didn't drop yeah but the client's still not trying it why is that debug console create ship sending join find a login as captain sending join create create ship for u u id but you've created a ship check if it's my ship their objects add burn ship instance yeah just check the history to be sure that was the right change and that was the right change at the time so there could be something else going on in that case could be something that i broke so let's add some more yeah so now we're getting into live coding here so let's get some more logging join game so it send the join which it did fine because we saw the player on the other side create ship for u u id what actually calls you this is in main scene game 109 whoa that's the things happening on my phone right now um call them the network process game membership event okay update ship with the u id try to get value doesn't exist so see it didn't it didn't actually send this message though this doesn't exist message in the logs so something something's still funky so the ship does exist i don't well so here's what i don't understand it this log message happened create ship for u u id with the u u id yep but the the thing that calls this function doesn't appear to be good is this create ship for u u id which right before it has an update message unless there's another place that it gets called nope i don't understand how that happens sending join which it did did that right let's add more debug yeah and i see a i see a message here from jason two dash that he says that quickest fix was to just pass the actual u u id and hold the player name was local only for now patched and pushed to get up did a quick test with a couple of dope lines and it looks to work and he shows a screenshot where indeed we see what we do not hear today that there are multiple ships up and moving around on the same on two different clients this instantiates a ship instance player objects try get value u u id that's the u u id that gets passed in out i don't know what out means somebody's getting fancy with their c sharp skills and i don't know what that even does out as a parameter that comes out of a function so basically somebody hands something in you stick something in it and then when it comes out of that function call it has a value that you want to retrieve yeah and looking at the number of changes to the client from the repo on main after that fix went in their ship everything added was um screen artwork so if there's a change it could be local oh okay the reason that we didn't see this message is because the player does exist because it was created when we created it if that makes any yep if that makes any sense because it was this client and not a different time right yeah so during the join we do we do that like reading somebody else's code it doesn't take so long to update create ship join game as player yeah so when you press it when the when the join button is released it tries to log in doesn't even say that either oh yeah log in screen trying to log in as captain join game as player okay so this is where we join the game as the player so it builds the command buffer and sends it returned true to do this always can't be true yeah so it sends the join message and then sets the label to our player name and so it's always successful remove myself queue free it does that yeah so this is where i'm confused because where's the server connection update from game event buffer yeah that's going to be okay here's here's where it happens yeah so we get the create as a message that comes in right entity game event buffer create so that calls the new ship create ship for create ship for uid so we do that and add the player objects yeah so what i'm going to do is i'm going to change okay first i'm going to kill the server then i'm going to kill this editor i actually don't think i had to do that and then i'm going to start the editor vs code attached to the client then i'm going to restart the broker the zooming stuff you added in was that recent no okay i'm just wondering if maybe the player exists on the client we just can't see it maybe it's elsewhere except for where i don't think the zoom has i don't think there is zoom in the client okay the player does exist on the server it's just for some reason the client's not drawing right exactly the relevant information so i'm going to add some some debuggy bits all right so there's the server here's the client i'm going to play this in the editor which will give me the remote stuff for variables and all that fun jazz there's the editor here's the editor remote thinking okay game map canvas layer login screen all right so when i join the game now let me actually do this process move command this is the server i want the client that's not what i wanted yeah so updates what does this update do it says update the ship with the ui update from uh okay so if we look here in definition update from again the position equals the position x and y the angle the velocity okay so this this should draw the thing for the for the player right when we get an update so maybe something's not working with the update oh okay hold on let's think about this okay so here's the message so when we get an update message update from game event buffer yeah so this is probably gonna barf out a ridiculous quantity of messages but just for giggles i'm gonna do it have a sneaking suspicion this is more uuid mismatch stuff i need to figure out a way to like only spit this out like every once in a while if that makes any sense yeah i need like a sampling logger yeah well i mean i'm sure there's a way to be like mod like you know i'm sure gado has some variable and for those who are actually watching and actually know something about gado i'm sure gado has some variable for like the current frame or how long it's been running that we could like divide by you know 30 to only do it once every other second or something all right so if i do this i have to stop it and then restart it i have a sneaking suspicion that we're getting updates for uid that we're not trying to draw or something like that so let's go here to the editor go back to remote and then go here and then join as cap in and so we're getting updates for fb whatever and so now if we look here is this the ship the ship doesn't even exist it doesn't appear to have created the ship um and player objects is not currently a public it's not exported i don't think here's the game yeah the player object's not exported so if i break in here um actually i'm going to break inside the game itself because what are we doing we're calling that update function so here's server connection we're calling ship update from event buffer egib but did we actually find a ship ah see oh wait no step into step over step over so it it found a ship so the client goes now about a ship can i can i access the player objects from in here i'm in server connection i don't think i can access player objects oh but i have the game don't i what line of code am i on i do have a game so if i come into the debug console game i do have a game here objects fb5 b1072 where's the fb5 b107 so like here's the yeah so it it's the right player yep let's see so what do we do here to ship update from event buffer egib here's the egib it is a 2d body update player body velocity forces here position it's negative 348 and 41 okay i wonder if it's just getting drawn off screen it could be a so update from game event buffer so that's a particular player ship no because look if we go back to the remote right we don't have any player scenes it never it never instantiated a player so i didn't instantiate the player even knows about the player right so let's trace backwards through that so let me get rid of this so did i see earlier on a different note that you had containerized the output of the client i containerized the the server oh you containerized the server okay so maybe because we have a little while left maybe we should talk about that too um sure we can talk about that so now we're gonna switch switch to talking about containerizing Godot in a server so if we come over here because like that speaks to our goal of getting it up on open ship and scaling it across yeah right so Godot server and Kubernetes i found this repo and i found this docker file or container file um and so this makes use of chained um chained build stuff in in oci um and so effectively there's a build container where they run the Godot ci image and then they just run the Godot editor uh headless and you feed in an export preset and tell it where to spit out the export and blah blah blah so i started with this and i was like hey great let's run it and it immediately exploded and the reason that it immediately exploded has nothing to do with this guy having done anything wrong it has to do with the fact that Godot community has made the mono stuff look very different and you'll you'll appreciate this momentarily when i show you and so when we pull up the container file for this um so instead of the version being like dot m or or dash mono it's backwards it's mono dash oh that's weird for the ci image that's not that's that's that's the first problem and the second problem is that from a zip file path perspective they have mono names based into a folder instead of just being the name and then the name is all butchered too so basically like i had to hack mono support into this container file which really wasn't that bad um the other thing is that the way the original container file was built the linux server zip file that the Godot community puts out has a single file in it and so they were using fun zip and and uh pipes and other stuff the issue with our sensitive issue when you're dealing with mono there's a bunch of like mono support content that's in there as well like native stuff that comes with the zip file that had to get captured and moved around so effectively i had to massage this container file a bunch to do a few things so first i had to pull the correct mono version image the export was pretty much not an issue um this stayed the same so then you download via wget the mono linux server which is headless and has none of the editor stuff it's pretty slim but then i like moved it from its complete big file name into a folder and then i had to move the binary which has the same name as the folder name into a another file like i didn't have to do this but but i did just to make it a little cleaner and then i had to massage the copy a little bit so um i needed the entire godot server folder because of the mono dependency folders the data folders that come in then i needed the whole export folder because when you build with c-sharp mono you get another data folder that has your like c-sharp dependency stuff in it and then i had to include our log i didn't have to include our logger config but i chose to include the logger config in the repo um and then lastly you know it works so now that i actually have a server um if i run this artemis come on come on come on so um oh different history uh so i i built the container file using the the normal syntax right and so now podman images i have um this red hat game dev server that's not too big right 159 megs yeah i didn't even look that's actually really small so if i run the container it should oops oh boogers um yeah like you see the mono 3441 there is pretty big itself but the game because that was the um that's the builder right that's the full godot everything with the editor in a container all the depths you know like probably like the dot net client you know what i mean like it's it's a giant pile of stuff but it's only only used for build right so if you're talking about distribution via container to scale servers like 159 megs like that's that's teeny that's pretty good so if i run this it should run and it it did it's initializing the mqp connection but it doesn't appear oh got it okay i know what the issue is um so this is where we're going to get temporarily stuck so inside the container it's trying to connect to local hosts by default but the way that podman handles networking local host inside the container is in a network namespace dedicated to the container so i actually have to tell it to use um i would actually have to tell it to use like um where's the podman network uh well i can tell podman about ip's and stuff but i'd probably have to use like the ip address of my of my laptop to make it be able to connect to our tennis the weird thing that i couldn't figure out is like it never seems to explode on not being able to connect but i don't think the server has that i think maybe only the client has that i i can't i can't remember either way um it it's not going to work so what i had started to do from a code perspective on the server side was i had started to dig into the um the load config function and this is where i was like i was going to check if we were able to load the file and then if we couldn't load the file we would check for the environment variables and then that's when i started to like dig into you know trying to be cute with like the coalesce operator like if if the value is null then use the default or whatever but like null is not a valid for an int and so like once you once you cast once you int parse like the getting of the variable you don't know that it's not and so like that's what you're doing at the very beginning that we commented out so we could move on and yeah all right so so we this is another sort of um roadblock here but what i could probably do for giggles is force the i could temporarily hard code the um url yeah the ip to be um local machines ip yeah which is one that's probably nice i don't want i just want to make sure it's listening on all interfaces it is okay hopefully the firewall won't interfere one nine two one six eight one two three six one two three six oh but now i have to rebuild the container right which actually is pretty quick right whereas normally you know you'd mount the file in the container something well so that's actually a funny thing right like neither docker nor podman nor any of these oci run times you actually can't inject files you can only attach volume right yeah so we either need if we want to make it easy we should move all config into a folder yeah that's when we could just mount the whole folder yeah exactly or we have to like do something funky and then that would be like open shift compatible because later we could use a config map or something like well that's the funny thing with kubernetes you can attach individual files like it magically can do it somehow with subpath like i don't understand how it does it but like podman and docker can't so whatever interesting sort of that a prio feature i maybe all right nope why oh i built it in okay the interesting thing about bash history is that somehow it's both smart and dumb and what i mean by that is like there's history from commands that i did in vscode that are not in the history of this window i'm sure there's some magic way for like bash history to be super universal but i always find that kind of tricky i use tmux a lot and i always find the history of tmux yeah and like you like exit tmux history and it loses your hash i don't even know yeah it's mapped to ttys or something like pseudo terminals or something like really low level so i don't know how much time that just took let's i'm going to do this again to shrink eagles i think it was pretty quick right well so this is cheating because i didn't even change any code so that was that was that's your minimum five seconds ten seconds which is not realistic but you know it let's okay here let's do like if you had to pull down the image and stuff for the for the mono if yeah so i'm doing no cash which which is basically if the image is already there that's fine but don't don't use any cached container layers so this is doing the full build which ends up repolling the zip file i don't know what that weird socket not supported error is i've been getting that a lot um it doesn't seem to actually have any impact on whether or not the build works or not go team ox heck yeah definitely hardcore team ox was here okay so the whole build of this godot project into a container took 32 seconds which is pretty good now granted this is a very simple small project with with small assets and all this other stuff so like that build time is going to be more directly correlated to how complex your project is and not so much um related to the container itself but that's built hard coded with an ip address for um my artemis so if i run this there is a good chance that it might work finished initializing a mqp connection boom and then if we look here we see that it's connected yep so i have now containerized my game server with godot running on podman on my local laptop but as you can see or as you can't see there's no ui like it's it's it is rendering the ui into the ether of nowhere land so firstly if i was going to do a server build i would probably want some flag like some environment flag or config file flag that says like skip all ui render thinking generation yeah be a headless be a headless thing but for giggles if i run the game client it should we should see um we should see the server the game server should respond to the fact that we are connecting an actual player what the ip that the client is going to no because the client's connecting to our tennis all right that hasn't changed on local host it's not connecting to the server so that that's another it's a good point though roddy like with this architecture i actually don't need to know where the game servers are i only need to know where my message broker is yeah which can be a system say again which can be a consistent endpoint or yeah right so i can i could you know and even further if we had lots of different games because of the way message brokers work and correct me if i'm wrong roddy like the the client and the server are responsible for knowing what the names of like queues and topics and stuff are i only actually need one broker so i can legitimately have like infrastructure for sure say again you could share it up to the point of where it becomes a load issue and you need to scale the broker in the messaging layer exactly i can scale my message infrastructure to handle the messaging load and independently independently of the game server structure right now now let's be honest like amqp is not over udp today so there is tcp overhead so if you're super latency sensitive you know this is not really gonna work or or there's there's an upper limit to where it will stop working because of your latency sensitivity but if you're not super latency sensitive one messaging infrastructure could support hundreds or thousands of games you know like so if from a big picture perspective we use this amqp technology for stuff like there's a whole system of like train information like passenger and cargo trains and the positive train control yeah i don't know how much of that is public but you know um many many many thousands if not millions of messages a day you know from lots and lots and lots of individual endpoints going to lots of destinations and all that other stuff like it's it's a supremely scalable solution but anyway so cap in we'll join and then what we should see in the server in the background is that a player joined which it did added player instance we're still having our bug here with whatever but like hey that's cool we at least made some progress um yeah like seeing the containerized seeing connect i mean i think that's that's pretty good i mean if you compare that you know when we left off we were in a very different place with regards to the tools and languages in use and all that stuff and now we're back here and we have well it's not quite visual but i mean it's a small bug we know that visually it's not far off multiple clients connecting to a server that's containerized and containerized in a way that uses a builder image and then actually has a slim runtime image that even like you could probably put like in an open shift build pipeline later for example right yeah the next the next step would be to well there's two options one would be to make it not use a native container build and just figure out some way to use like a tecton pipeline and have it do sequential sequential build steps like without an actual container file just you know make each of those container steps here actually i don't know why i'm explaining it but i can just show it um so instead of using a container file this would be a step in a pipeline where we run this image and then do the same command inside of it and then we save the output to temporary storage and then this would be another step in the pipeline where we fetch actually we would pre-build the image that already has the linux server in it and then we would actually just inject this you know so like there are ways to simplify this that don't require doing a container build but then we'd have a knife a nice fancy pipeline and if you know we were good enough to uh if we understood how to do testing with Godot which i have not even begun to look into um you know we could run our tests in an automated fashion and and then ultimately just automatically deploy the new game server um as soon as this was all completed but i really want to understand why the client's not working so we get uh no so we got to go all the way through the initial thing okay so when the join button gets clicked oh that's on its own it's a different scene login screen okay so when the join button is clicked execute the join game as player with the value of the text field so join game as player sends the message sets the label of the text field which it does and then just is done and so when we get a create message we're supposed to create a ship and then update the ship oh i think i see what's what's going what's going on here so new ship is create ship for uuid no yeah this does create an instance and here's where it adds it we didn't see it and see that in the uh node higher clearly right oh yeah it's adding a child to the canvas layer so there's definitely something a little weird um i just tried it a couple of times and on the third try i can now see my client in the client and on the server so hold on it's a child of it's a child of the canvas layer so that i actually may have not just not been looking in the wrong place so let's do so maybe it is randomized outside the area of the screen even though we didn't see it before you know that's i bet that is true well but it also doesn't display the sector correctly but maybe it never did are you seeing your ship you said right i see the ship at the moment so the third time the sector or sector still say x no i have x and y and my underneath that it says my hex no no no in the upper right hand corner oh it still says sector x yeah okay so yeah so i bet it's just not zoomed in correctly and so the question is how i just got to figure out how to make it zoom in correctly um but just for giggles to make sure that we're doing the right thing so i'm going to play the server i think i still have the broker running i do yeah and so this time when i added so i originally added player two and then i added player three and i can see both of their uuid's on the server and i can see both of them on my client yeah i i think it's probably just a centering issue i think so i think functionally it works except for the fact that sometimes we can't see them yeah so let me do this again cap and join game and then if i go into the editor and look at the remote it's a child of the canvas layer here we go ship things player ship so here is 2807 uuid is not public but where what is its position yeah 457 and 293 so it's probably just off screen so let's look at the server because the server has code that does that fixes this oh can we get this in time let's see server server server things related to the debug ui so it's built into the zoomie bit oh see there's a camera that i don't think we have in the um in the game yeah there's a canvas layer and a map overlay but i don't think there's a camera i think that's the problem now that i can code this fast enough to grab the camera and zoom by the zoom factor yeah so here's where we make the camera current i think the issue is just we need a camera to to tell it where to render are you still with me roddy i see you moving i just don't hear you i was right i was muted i was taking pictures from the uh would you want to share your screen instead no i just uh i just i just had some funny other behavior happen oh while i was taking screenshots um i accidentally hit the key for one of the ships to fire a missile but on the opposite client it actually looks like a ship was fired now i see the ship continuously appearing and shooting of course yeah yeah yeah so that that has to do with like what we're like stuff that we're drawing yeah so the issue right now with the client basically for those who are still paying attention is that um the the script like where the player ends up on the screen is actually outside of this box and we don't have any game camera to focus on yeah a player so the issue is basically we just i need to add a camera to focus on the player um and so if we go to the internet here gado camera follow player how to make the camera follow the player and gado how to make camera follow player and gado look at all these stack overflow when i add the camera node common tooling right the player is stuck in the same place and can no longer move i don't think that's the problem here make sure the camera note is a child of the player and the camera has no scripts okay so if i open i'm gonna quit the editor so i can try to remember how we did this because i don't think the server nope we want the client if i look at the scene file for player does it have the camera hit points position hex playership sprite hitbox oh it does have a camera but it may not be in the right place relative to the ships um yes but i think all we may need to do is when we once we have a player that's us we need to make their camera current this is the ready that's not what we care about process join game as player that's the same looking at you i think probably perfectly point uid yeah so check it check if it's my ship so that's the issue right now is we don't actually know who we are oh gotcha right because the game the game is storing or was storing player name but then if you player ship my ship where do we actually set my ship my really it doesn't sound like it's anything too complicated yeah i'm hoping i can just do it here in the next like minute or two not found my ship yeah okay so let's see so if we go back to the game so here's nope we want the login screen so this is when we join the game as the player so if we go back to game join game as player sending join with uid name it's player name okay so this is where we would set the uid because remember we're using server connection uid as the uid which you will have to figure out how to fix this so for those of you who's watching don't don't just don't worry about that first string my uuid so here's where we would set oh actually i don't even know that we need to do that so where's the create ship for uuid got it okay so here's where um if uid update ship with uuid so at the moment we're saying it's updated but it's not created no no no hold on i'm i can't think and talk at the same time i'm not that smart so create ship for uuid update yeah okay so that's in the game create ship for uuid what uuid is this it's the uuid of the buffer which is going to be the player so here if uid equals server connection dot uuid two equals yep mistake pair programming for the win um i think these have to be in parenz in c sharp they do so then let's see player objects this layer add child player ship thing instance camera camera hold on the middle of the server where we do this a current player camera equals get node in the player for camera okay so we'll do this okay so the camera is going to be player ship thing instance get node camera 2d player ship camera 2d that is a player ship thing player ship yeah actually we don't need to do this because this is already a player ship and then we'll just do the make current so i think this will do it so basically what this is saying here we're going to try it we'll see so we already know that the server connection uuid is our player's id yep and then this uuid that's coming in is the uuid that was in the message and since we're creating a ship with that player identity this should be like player uuid or something we're not very good with our variables anyway so blah blah blah if the uuid of the message equals our uuid then take whatever the camera is for that player object that we just created and make that the current camera so fingers crossed open good though editor what am i doing yes okay so server on the server okay let's do and it's thing thinking thinking thinking chug chug chug and so some of you might be thinking like oh wouldn't it be cool if the game client like didn't need a server to be debugged we'd thought about that but the reality is that you end up writing a lot of the server logic like into the client just to be able to not have to have a server running to debug and then like wouldn't it be cool if you didn't need a broker to debug but then at that point like you're writing a bunch of like fake messaging implement so it's just it's actually like this is the simplest thing to do is to run a broker and a client in a server which i know sounds terrible but like it's really not that bad and resource-wise it's not actually that intensive starting out as long you know means not like there's a lot of players when you're doing this type of cycle for development for giggles so uh chrome by far is using more resources than godot like one more yeah so godot is using 100 megs of memory like a gig like i mean nothing compared to you know your browser is using more memory than uh you know than this is so anyway all right so what do we got we've got the server is running somewhere where did its messages go there we go okay servers running here's the client fingers crossed everybody for all your viewers at home nothing no joy so maybe it's not the camera or maybe it's not just the camera yep something weird's going on but there's but as i said i didn't make any changes here other than making sure that that uu id line was in place and ran it a few times and then after like two or three times it was working okay so it can't be anything too major well so this camera's at zero zero but i don't i don't know what that means in relation to the client but the ship is at negative 161 477 so what happens if i do no luck no joy all right so stay tuned yeah almost yet to be found but at least it i think we're possibly losing Eric also like his rpm 65 535 rpm that fan must be really working hard at the moment am i back yet you are just back uh yeah that was meltdown due to excessive log message generation because you had there was a log message on the update frame update ship with uu id that is in game i don't don't want to log that every time bad things will happen uh bad things will happen all right well that's probably the stopping point for today we just got to figure out why why the camera's not showing the player or yeah or maybe we can try to deploy the server and see if we can connect to it next time from yeah sure hopefully we'll actually have a game that like everybody can play we'll maybe have a client that can be downloaded so that a bunch of us can get on there do some terrible horrible load testing given the matter that that camera is one by one that is a good question mr programmer or the programmer um the camera is one by one in the server but then we set a bunch of zoomy stuff on it i think we make it current and then let me actually take a look at that player well the node definition doesn't have anything about size so you should be default you could be right um i don't know actually how to figure out let's open the editor for the client i don't know enough about kado cameras to actually know how to answer your question meaningfully yeah and when we were doing pot escape i did but i long forgotten scene open scene um court scenes player camera zoom is one one offset zero zero i don't i'm not sure what you mean by it uh in the ui under x and y it showed a spot to change the life yeah we we i tried changing that it didn't uh size i don't see size i see zoom i see offset anchor mode tating current let's uh let's try having played with kado so i could be wrong yeah me me either let's go here camera follow script position of the camera equals the player position maybe we need to do that we didn't actually set the player position it's worth a try i would think the player position will be being set up or the player ship position is right because we could see them when it was working here i could see both clients i could see both ships in both clients so the player ship and i could see them move so i can only assume that i think you got lucky in the fact we could see them within the camera you mean yes yes yeah because it wasn't following right like the ship moved in the camera didn't that's where uh where's the maker create oh but that doesn't always happen so let's see update ship with uuid also add this there if must have joined before us or it's just a regular process we never set my ship oh well then maybe we can do this all right i'm actually gonna do slightly different and what does make current do um it makes the camera current from a godot perspective the current flag uh sorry c sharp versus gd script makes this camera the current camera for the viewport if the camera node is outside the scene tree it will attempt to become current once it's added um viewport creates a different view or a sub view children 2d nodes will display on it children camera 3d blah blah i don't i don't think we have to worry necessarily about that i don't know that's necessarily doing what we need in that case right maybe we need to be well if there was no current camera because like once you end up with all the players like if you had another player join you you don't want that camera to like take over so the make current is probably important but i may not be probably also need to set the camera position but it's weird because i don't do that in the server right and it's and and he just copied the same code so on every process frame we look at um we look at the the text field and say if the text field has if the text fields value is in the player objects then find its camera and make and then make that camera the current camera right and and looking at the note the scene graphing gado the camera was a child of the playership right is that what i saw yeah so you're right then in that case then it shouldn't need to be done manually because the traversal of the scene tree should update the nodes in such a way that the camera is a child of the playership which makes that apparent child relationship and they're attached yeah i'm just gonna i'm gonna do this again for giggles now that i don't have this broken log message stuff i also want to make sure that it's actually working right so here we go so here's the server client will come up any moment oh client's already up so this is the client here's our log messages so camp in in the game aha okay so map canvas layer ship things okay so i i just have it's code error uh so when you remove playership slash camera 2d i thought i didn't need it because it already was that but apparently it was not ship things playership camera 2d okay so i still need to be specific in there well i thought this was already oh it's it is a ship thing my bad yeah so it's a playership um that one right there hang it yeah so this still needs to be playership ship slash camera 2d even though you're calling it on the playership thing instance well i thought i was calling it on the playership this is actually the ship thing oh i see ship thing so this has to do with um let me i have this is a node hierarchy so the ship thing is a node which has this stat node which is all of the labels and then it has the actual kinematic body object which has the sprite the hitbox and the camera and then some transforming bit which i don't remember why that's there i think it has to do with clamping or the camera and then the actual camera object so it's funny i just didn't see this error message previously so let's stop the client and stop the server oh man if this works in the last like five minutes of the stream that'll be funny so let's restart the server so that it again because we don't have an easy way to delete players that should be a if only we had people who wanted to help us with this that want to write code they can write the tools okay here's the client so i fixed that with the playership so let's play an editor okay that's doing this thing right there's the server here's the client there's the client in the background captain join game oh look at that still not centered correctly no but it's better place and we can see it and we can see that we can it's yeah so we need to center the camera fire to ship ha ha ha ha i want to give you one up another client oh um no not easily because you need to open up a new kadoe instance in a new instance of the same project well here so if you if you really want to yes here's what we can do um let me let me expose hold on let me expose it with engrock all right so you roddy do you see this i do yeah can you read that so that in your client you need to set that as your yeah i'm trying yeah so what i'm going to do is i'm going to fire up my server which i can do fine with local host i mean i got that for you again roddy and just one second i'm just about to put it in here i just switched over from linux back to the mech and my automatic key combinations are now all wrong oh no two dot dcp in groc dot i o correct 12 8 56 is that correct yes 12 8 56 five six all right so let's see what happens when i save all right and go back to my client yes you don't need to run a server you just need to run that's right just the client see what happens something between me and you so sending join with uuid but i do see that you don't see my uuid i don't see a connection i don't know and i see that it's connecting to the wrong place so there's something i did wrong here locally let me see if i can find the right window once again yeah there's no i don't see any connections from you did you edit the server config or the client config a server connection dot cs in the srt project let me do it by the command line here close down the server in the godot client but you you need to be running the client not the server i was indeed running the client okay so you edited client dot cfg and resources no i edited the connection in the actual file which gets overwritten by the client configuration file oh in server connection dot cs and that gets overwritten by the config file that's right which is what i'm updating you now yeah yeah i got it okay yeah in the absence of a config file that would have worked yes oh 20 seconds right 2.htcp.ngrock.io one two eight five six all right one two eight five six and see what happens and oh still connecting to the same thing what yes i don't know why and the client config is not visible inside the godot and i'm sure i edited resources that client config and it has the right server strength do you want to see her on your screen nope but i am gonna update this manually again here 2.htcp.ngrock uh there was some changes i made earlier when i was doing some testing because um i had some issues earlier let's see here oh i see the problem silly me so i'm sshed in to my linux workstation uh and when i edited it was on the linux workstation got it let me try it locally too many machines too too many yeah e too many servers yes indeed that's the whole problem 2.htcp.ngrock i'll call v56 and we'll try it right out of the gate here again if my window would stay up billy connect wait oh open one connection that's me there's six oh a player of course i don't see it on my side but you see me but i don't oh yeah because you didn't you didn't edit your you don't have your code changed nope but it worked great it worked fine yeah so let me let me play an editor hanging on i don't know that i'll see you so for those who are still watching roddy is connected over the internet to my message broker running on my laptop he's in the game so this is this is roddy's player in the game i'm gonna now join the game and now i don't see myself somehow the camera make current thing didn't didn't work right but we're we're both in the game yeah and there's me turning around even though i think it's something weirdly reversed in some way because when i push forward i go backwards really i pushed forward and i went forward let me turn so let me try to go toward you now i am good well i'm following you so that's good we're going to synchronize flying over i think we're at the edge of the play area oh so we're stopped oh we should be now can't seem to get away from you though oh there we go now i'm gonna slow down and now i'm running away where's my i'm trying to find so hold on i'm gonna slow down if i can get to like zero dot zero six five four three two one five five five okay i'm trying to try to get to zero dot zero so that maybe i'll appear oh no cheater you didn't hit me now it's good to see that that worked at least right like i fire from my client here and the missile was shot and it hit you and at this point so yeah like that's good yeah to sixty two seventy i'm trying to like i'm trying to get myself onto my screen oh i found myself okay hold on i'm gonna go to the camera thing in the editor uh remote hey look i see you on my screen now yeah where's the player ship camera 2d who's i don't know whose camera this is because there's three three players so i think we got some stale some stale stuff going on yeah probably from the one we didn't see earlier that i quit and rejoined from player oh could be could be so i mean ultimately like the idea here works and works okay using gado as the server and as the client with a messaging bus using protocol buffers in between right and like all the bug logging that comes up in gado also works and let us to see the camera not being set quite right earlier on the um on the player ship and we're able to inspect like this is this is all things we've gotten by moving to gado we can go and visually inspect the node just yeah just having the tools and the editor and everything is like so right yeah and you know we're using a game engine which is not explicitly designed to be a server as a server right like that's pretty awesome all right folks well thanks for watching today i'm we roddy and i had some fun and we got some things working we got some bugs to file and fix uh with camera stuff but um yeah man this is rad this is great good restart i think yeah cool beans all right i will let's see where the captions graphics is there a ending video well there's a ask the open shift admin outro video that i could play but there's no like stream ended video so hmm stream ending okay i'm going to go with stream ending we'll see what happens see everyone thanks for coming cheers bye