 I guess that means we're live I guess this up here for now so I can look like I'm looking at you I'm looking in my in my lap. Hi. Um, we've got some weird backgrounds here. What is this? Oh snowman I could use some cooler weather. It's definitely hot here in Atlanta. You find hot where you are? Uh, so in freedom units that is 82 Nope, that's my that's my laptop temperature. Um, actually Probably about the same actually. Yeah, uh, let's see 87 which is I don't know like 35 in in metrics one Ish 88 And it looks like rain is inbound Yeah, I think it's um Only 23 Celsius here. So I think that's in like 23. Well, you're in like you're like Maybe even high 60s country above the north pole. Oh, yeah, this is perfect. Yeah But to be fair it has been really warm here. We're not really warm for us is 29 30 Celsius like High 70s low 80s, maybe got it um Yeah, so let's see last time. I don't actually remember. What did we talk about last time? Oh, we showed that we actually had a client last time I think was like as far as we had gotten and it worked. Yeah, so We had like a I took a trip to do some stuff and because I was like not in the normal east coast time zone I was in europe it turned into like a mini coding retreat because Yeah, none of my meetings were happening or I'm not going to go to them because they're you know, nine o'clock at night or whatever So I actually was able to get quite quite a lot done. Um, so let's see. I'm going to share my screen And this is going to be hot mess entire screen Oh, my phone is telling me to do something What do you want me to do? I like that ring tone erica. It's pretty uh It's pretty retro Yeah, zelda. Okay, sure. Uh, whoa, look at that. Okay, move this out of the way infinite screen loop Come on get bigger. All right. Don't get bigger. See if I care Okay, um, this is the server open the editor I don't know what infinity tunnel mode That should have gone away. I would hope if it's gone away now. Okay. Uh, view appearance In control equals this is work This work, um We'll go one more. Oh, maybe not close enough Okay, so one of the things I did was, you know, eventually this has to run on open shift And so I was like, well, I guess we need to build the server into a container or something. And so I messed around a little bit with um good dough and builds and exporting and some other stuff and So what we did or what I did was I had found Oh that went in the wrong window. Come come on. Come on. Come on So I found this cool, um PAS zoo PASU uh, gado server and kubernetes um Which builds a container image. It was basically it's just a container file with some deploy YAML stuff for kube I was like, okay, this will be a cool start and then I started digging into it And what I quickly realized was hey folks, we'll contrast you. Oh, that's you ready. Um I was like, hey, cool. Let's let's run it and then immediately it exploded and I was like, oh, I wonder why oh Good dough or mono. This isn't mono bummer But so at a high level what this thing does is it grabs the image that the what I think Is that the good dough project uses for their ci for their own builds for the actual engine itself Um, and then it runs an export in that container Then it runs another layered step with a very minimal image to grab The actual good dough server like the headless binary for for gado itself And then ultimately it copies The built artifacts and the server into like a local folder And does some stuff and then it runs On when you run the container it runs the server, right? so I ended up having to hack on this a bit because The good dough project uses like this mono prefix and the urls for grabbing things is all bizarro land So I had to had to sort of massage the heck out of it. So, um, you know, a mono version there And then I had to change this folder because it uses this mono prefix url whatever and then I had to grab the mono server and not the regular server And then the mono server has some subfolders So I had to change this so that it actually like Copied the server and the mono c-sharp dependencies and some other stuff blah blah blah And then we have this logging config file that needed to be present So that got copied And then ultimately it does it does the thing, right? So it's been a minute since I built the container version of that so Let's do some some do it live. Um, let's see build SRT So the idea is we can containerize the the server rolled out on open shift like consistently scale it up move it around Yeah, so what I what I tried to do is set up a um I'm just a fail a bunch of fail book today history This is my first time to this dream. So I wanted to make sure I don't want to like Is it oh it's just rotting the other one or no, yeah, you know, but it's a good point We haven't um, we haven't said anything so build container file good dev server good dough test. Okay. I think it'll be 849 So I'll kick this off. Yeah, so the goal would be That we would do our own ci so whenever anything gets merged to the main branch That would cause like quay to build the container image And then we would do some testing or whatever and if we like it then we would give it a real Image tag and then change whatever the public deployment Of the game server is so that it would start using the new the new server, right? um Okay, so that appears to have blown up. Oh because I moved The logger config file into a config folder, but it's still it still should work So let's do this. Um So here I've got my Artemis server running Locally, um, I did put one like on a t2 micro in amazon so we can maybe dork with that today If I can remember how to access it Um, but Artemis is running here. And so if I do pod man images What we see is the srt aims. Nope. That's Oh because they'll failed So it didn't actually right. Okay. Sorry So let me just comment out this one And do that build again Um, there's probably a smarter way to do this so that it goes faster Because it ends up thinking that it can't use cached stuff even though nothing has changed um We we those errors are actually not errors like That has to do with when Godot does a build of our project for some reason the way we're compiling Pulling in protobuf like the c-sharp files that get generated from the compiled protobuf throws Godot errors But they're not real errors like it still just works fine. It's okay. Yeah, it's a bit confusing. They're not important errors How about that? So here's the successfully tagged global hosts are coming up as errors, but they're really just worn probably One one could say okay, so 21 seconds ago. Here's our srt server um If I run It's he Yes, sir What have you guys like explained sort of the architecture before I guess I'm assuming in the past everyone probably but we can we can go back and talk about that In a second. So let me run this and then we'll see what happens So It started to work and then immediately blew up because Oh, I remember what what the issue is so Um, it's trying to connect to localhost 5672 but remember that Podman especially and and and other container run times. They do network name spacing So localhost 5672 is actually inside the running container and there's no amqp there So that's why it explodes Immediately right so from a container perspective what we actually have to do is this is a perfect segue I'm glad this blew up this way. We need to tell the game server like to use a different destination which brings us to a code change that I made which was hey If we're going to run in a container we need to support environment variables as like configuration You know, yes, you could inject a config file in kubernetes with config maps and that makes it easy but You know the proper way to do it is with is with config as environment Oops, don't do that. I don't know what that was going to do. So that we consider best practice Yeah from from a containerization perspective best practice is always use use environment variables, right because Um, then you set the environment variables on deployment for the environment So friction uses this set of variables and that way it doesn't matter what gets deployed You don't have to worry about editing a file. You just whatever the current environment variables are. That's uh, that's what happens So we want load config and so Like we're going like a bunch of customers that I talked to you like that's one of the first things like that comes up like how do I If you're going from this mindset of game dev In a non-containerized world to going to game dev and containers like that's one of the first things you kind of got to get Fixed in your head because everything in open shift is like this software defined networking layer and so like You're going to have to do service discovery and all sorts of things if you're hard coding those things because you assume that they're always in the same place It's a paradigm Yeah, and and not even specific to open shift right like containers generally kubernetes specifically Like regardless of whose kubernetes solution you're using right, you know, we'd prefer use open shift But if you're using, you know, amazon or what or uh google or whatever Azure, um, you know, this is sort of best practice generally when it comes to containers and kubernetes So what I do is I say hey Same as we used to do try to load the config file If the file was loaded successfully read the variables. I know that sounds dumb and backwards, but there's there's a reason Sorry Read the variables from the file my bad. That that's not done more backwards So we look we try to load the file if we loaded the file successfully we set the values out of the file Then after we set the values from what we find in the file We immediately overwrite any That um, we're set in the environment. So environment variables trump File-based configuration file-based configuration trumps default Settings of the server so from a priority hierarchy perspective And this is kind of best practice from a container right like there should be defaults That will cause it to presumably not fail in the widest array of conditions then Use or look for a file and then if we pass anything in via environment Like that's ultimately the the the most important option or version or whatever you want to call it. So here I go Pull the stuff from the environment anything that's not null overwrite and then Spit out whatever it is that we actually did So pretty trivial pretty simple. So what we can see is the url The Where do I get the url? Oh annoyingly so One caveat here is the way the server is done and this is not a good practice The amqp configuration for how we talk to the message broker and and and jude ash We'll go back to the architecture in a second Um, this has its own config thing which isn't necessarily good um So it has its own config thing, but it does the same thing right Get the value out of the file if we found it otherwise override it with the url from the From the environment variables. So what I need to do is I'm pretty sure I did this once before apparently I did not highlight. Um, so I need to pass in the environment variable equals Uh ip adder What's the ip address of my laptop? It's this Uh, what's the format of the string? It's like a mpp Yeah, I am Yeah Okay, this should work Whoa, wait, wait Wait Well, it didn't say finished initializing, but it didn't blow up We have a connection So that's a new connection So that that's a little concerning go back to init Do we not call it init? I thought we called it init command receive scheme event send command initialize Initializing mqp connection and then finished initializing It's it never even said it was initializing. That's weird. Oh, I bet this might be causing it bummer Anyway, so we'll we'll we'll fix that later. Yeah. Um, architecture. So For those who are watching, um, we actually have a web page now srtgame.com Uh, links to the different repos. I guess we need to add a one for the, um Defensive programming. Yes, indeed. Uh, we need to add one for the new protobuf But if we go and look at the architecture really quickly, this isn't entirely accurate because we're not using phaser anymore, but basically There is one or more servers That get messages through this message broker There's a client the game client connects to the broker and then using protobuf, which is a binary message protocol buffer thing We communicate back and forth between the client and the server. Ultimately, we might persist data into Some kind of data store maybe the the red hat data grid, which is the infinis band project Someday we'll get authentication working with key cloak slash, uh, red hat single sign on But this is kind of a high level architecture of of what's going on and potentially like other microservices too that are TBD undefined is yep As we yeah, absolutely good point like player chat systems and all that kind of stuff could still rely on the same messaging infrastructure, right? Yep, and like uh, like the chat lobby thing, right? Like that's probably going to be some webby no j s microservice Right the talks to the same back end Yep, um, okay, so I don't want to fix this right now. We can maybe fix this later. So what i'm going to do is Just run the game server locally Um, so if we see in this config folder I've got the server config which does talk to local host, which is fine because i'm running this on my laptop directly Um, this is i and i format stuff. So I just need to do srt. Godot server Um, this is using the standard export buildy process that Godot ships out of the box to to export for linux x11 Okay, and so we see we've got this, um mqp connection running and then in the background here is it's not really the background So this is the game server Which has a ui which we don't need if it's running in a headless mode um But this is the debug ui that some of you have seen before Depending on when the last time you looked was I added this like selector That you can choose which player you want to focus on and you can delete them. You can join new players, etc, etc So that being said, um, What do we got here? This is The server which I actually don't want so now we're going to get into some like legit Godot stuff um straight up Godot stuff. So what I did was um I made well, I should say I incorporated some animations that caliq made uh, caliq's another gentleman on our on our team here um, so this is the client we have The support scene which is the missile Come on missile. Okay, so we have this little missile dude add And then caliq made these cool animations for like flames and explosions And so what I did was I just used a regular Animated sprite and pulled in a bunch of images. This is 100 standard normal Godot stuff Um, it uh, it does not start as playing we we set some of that in code and then there's this explosion animation which Uh, also Uh, same kind of thing right standard animated sprite, whatever. What does this mean? No, it has one connection. Uh, there's a signal right, okay, and I'll explain that in a second So if we go to the actual code for Space missile, this is the client. I want the space missile code Um, so we do some and again, I'm certainly no game designer developer. What I'm I'm barely even a coder, right? So this is all my hack job interpretation of how things should happen So what we did, oh, let me do one one other file. Um, no, we're gonna start With let's see. What did I do it? Um Okay, so when the missile gets added to the scene We find the node for the animation of the flame and we find the node for the explosion animation And these are set to to i'm going to use the term global I probably don't i'm probably not using that term correctly Class instance, whatever variable one of you programmer guys you tell me So we've got these two variables that hold the node references So when we go into The physics Where is launch missile animation launch? So when the when the node is instantiated Sorry when the missile is instantiated. I think I set the um The animation to play. So let me find the fire missile Had to group missile my player All right, hold on. I know i'm like all over the place here. I got to remember what I actually did Expire To see if it was launched and if the frame was created in 30 play travel, I think Ah, okay, got it. So there's two there's two different sets of animations for the animation Why I did it this way. I could have all made it I could have made the explosion in animations, but I think I remember why I did it So we've got this launch Animation, which is like a little bit of an explodey kind of thing mushroom cloudish And then there's the travel animation, which is just like A flame front propagating, right? Um, and so if I look at this There's a point at which I tell it to play the launch animation, but I don't remember where That is hang on a second and I will find it That's expire update. Okay, so we're gonna do this when in doubt Oh god, that's terrible Not assets lots of files that are launched really Why does that work? There we go main scene game. Ah, okay Found it Basically when you hit something else, that's when you want to like make it explode probably No, no, no, no, no Create missile for you ID. So so the way the way this works from uh from now We're going to like back up all the way through the message. So what happens is um The way that this is temporarily designed and and the reason I say temporarily is we're going to talk about performance issues in a moment The way this is temporarily designed is the client is extraordinarily dumb It doesn't really do anything locally. It pretty much is just a glorified input output device And and some graphical things So when the player presses the shoot button What happens is um Let's see. Where is that? So if they've pressed the shoot button We process that input and when we process the input we create a message and then we send it to the server So right now when the player presses shoot the client does nothing other than send a message. It doesn't draw anything At some point the server is like, hey cool Somebody asked to shoot I'm going to create a missile and I will tell everybody that a missile was created And so that that's in this game event received, right? So we receive a game event We deserialize it and then we process it And when we process it we look at the type of message that it is Oh, it's a create message cool. Is it a player? No, is it a missile? Hey, yes. I got create for a missile So then we go to this create missile method The create missile method finally in the client is actually going to draw The missile so the first thing we do is we check if there was already a missile Because if there was something weird happened like We actually got the messages out of order or whatever. So which is never mind If it actually doesn't exist if it's a legit like we should make a missile we we instantiate a scene of missile Blah blah blah and then here's where we tell it to play the launch animation, right? We set the frame to zero And we play the launch animation Awesome So then this is where I do hacky stuff What I should do is use a signal here, but I I didn't I was even more ghetto than that and terrible So what I said was every time we process The missile so basically every frame check Are we still playing the launch animation and did we get to the end of it? If we did if the animation is still set for launch and we've reached the end Go back to zero and then play the travel animation Ugly hack shouldn't have done it this way, but this is what I did by accident Okay, great. So missile travel travel travel travel travel. Hey, that's great. What happens? So the way that the game works right now you fire a missile It goes and then eventually it disappears if it doesn't hit anything or anyone So the server will send a destroy message For a missile that is removed from the game, right? So if the message is about a missile then we destroy missile with uid when we destroy missile with uid We call this expire function On The missile right so what does that expire function actually do? Space missile. Oh, I could have just done this my bad. Hold on. Hold please Okay expire So we log a message because we're good programmers and we log everything um We hide The missile body Which is the the the sprite We hide the animations Again, this is dumb. I could have done it a different way But you'll see why in a second we stop the regular animation And then we play the explosion And then we set the missile owner To none This is where it gets sort of important and and critical, right? In the configuration for space missile in the scene There is a signal connection For the explosion animation being finished To run a method unsurprisingly named On explosion animation finished Why don't we do this? Okay on explosion animation finished We remove the missile from the scene tree And so I could have maybe done some like hacky or logic where I checked which animation Was playing And when if the explosion one was the one that was playing and finished like that's when I remove it from the Whatever so again the reason I set the owner to null is because we we don't want to disappear the missile yet Because we still have to play the explosion We don't actually disappear the missile out of the scene until the explosion animation is finished Kind of makes sense seems a little hacky. I'm sure some good old expert will tell me I'm an idiot, but It works. It's functional Probably terrible performance, but you know We're not we're not building the next overwatch here We're going for working We're going for working. Yeah, we're going for function and then maybe we'll make it work better So there was a horse trainer that a Long story short I used to work with and her saying was a get it done Get it right Get it pretty So we're in we're in get it done mode right now eventually maybe we'll get it right, huh? Very applicable Yeah, okay. So, um, what are we going to do? Let's go ahead and actually run the client So I can show you the animations And maybe it will actually work So what's happening right now is Godot is building the client under the covers Um, because that's what happens when you run it with the s code. This is the errors that aren't errors And then at some point the client should pop up My computer is probably going to melt down any moment now Can you guys still hear me? Yeah, okay. My load average is 10. That's usually a bad sign What can I turn off if you disappear we'll take over Yeah, um, okay, so we'll be doing well, I'll be Eric since I'm Eric Four accents. That's my actual handle for stuff. Okay, so join the game Hey, look stuff. So a couple other things. Um I think we're gonna lose them I still see a screen No, I think I think we're losing your audio Eric We might have to pivot into showcasing some other aspect Of the mouse is moving Can you hear me now? Yes. Yes Load average is 21 And we'll See how Trying to save my computer Eric you still there Yeah, can you hear me now? Yeah, clear again now Okay, I closed a bunch of browser windows and bad stuff Yeah, you would think that like an i7 with 32 gigs ram would like get the job done Computers suck man. I don't know what to tell you. So okay, so server's running right? I can spin this ship. What? I was just saying you it might make sense to have a second Laptop to just do the game and share the screen from there and that way the live stream doesn't Because you're doing all the live stream stuff too and that's probably what's yeah, but that's browser It's like it's really only my webcam. I'm not running like OBS or anything even locally, right? So it's it's just pulling browser. Um, anyway, so Ship moves around pray It goes it stops And then when I fires the missiles Uh, the first one sometimes takes forever and then just like vanishes Um, the second one usually works a little better, but this could also be Because I had um so much What should we call it like load average spike that the the messages Might be taking a long time to actually like make it in and out Um, so if I restart everything Uh, there we go. We saw an explosion Yeah, yeah, but you can't you can't see like the propagation because it it moves so quickly. So i'm gonna stop everything And then restart Okay, so we'll run our 10 minutes. Thanks when you're on it locally without One more time See if this works a little better But this actually is a good timing because it's going to lead us into our performance discussion about Messaging and updates and deltas and all that other kind of fun stuff So let me see if I can get this to display well enough for you all to to see it My fan speed is 34 000 rpm 34 000 now it's 65 000. Yeah, something's wrong with the display either either the fan is broken or something's wrong with the display Um, but anyway, okay, so here's the ship the fan definitely would be broken. Here's the missile. Nope still Still acting weird This is actually oh there we go. Whoo That was a nice a nice low one But you can see that we've got very weird variable performance, right? Like the missile fires sometimes it takes forever And then it like is here and gone other times. It's really fast And it it works, right? Yeah, so like we've clearly got an issue and again this has to this relates to like Player presses the shoot button it sends a message to the server the server figures out what to do Tells everybody. Hey a missile got created Comes back to the client the client draws the missile and then receives updates about where the missile is from the server client does nothing other than display what it's told about right and so that's expensive From a latency and throughput perspective. So what we started to talk about was um like Why why are we doing it this way? Is there a better way? And the other thing I noticed was like, okay. Well I know if there's a missile that's been fired, but I actually don't know anything about the missile Like when it's going to expire I know what my speed is But I actually don't know what my top speed is so I can't display like a percentage or a bar or whatever And so that opened up two conversations, right? So the first conversation was hey, you know, we probably need to Look again at What we're doing with our message structure If you will right like we we originally had thought we were going to use proto sorry box 2d for physics And the message protobuf structure was all built around box 2d and we didn't do that or we're not doing that And so now we've got all this unused cruft And then we're also Not doing anything with the client the client's not doing any interpolation or guessing or whatever And so in the case of like a slow message The the user experience on a client is pretty bad So i'm going to stop sharing Because i'm going to let jason share and if you want mr. Jason You can walk us through Some of the sub modules stuff you're doing and the proto changes and some of those things. Is that is that cool? Yeah, that's cool And then I guess just for to get everybody oriented if you haven't tuned in before like the reason Like we're what protocol bumpers are I don't know if you've covered that in a past stream But like this short we did but it doesn't hurt to do a two second review Yeah, I guess the two second is like basically it's this language independent platform independent way of Like serializing Our data to communicate it from the client to the server from microservice to client server or whatever however We need to communicate it. This is our way of representing that data that definition of it So let's see if I can share Does that work? Yes, but I have to turn it on which is weird. Okay. Now it's on I see your screen. Cool. So where we were was we had been So in the game dev repo everything we're doing is is open sourced and We have a server and we have a client So if we'll just look into the client real quick and see In the networking section, we have this proto folder that had these definitions so like if Can you bump your font size up just a little bit? Yeah, that's good. So we were talking about um The missiles so I think the missile would be in the entity game buffer Right. So this is its type. It would have been like type missile and it would have had a Um a body that's related to the missile That's this is the data structure that we're communicating the data in and then the body What we were sending was all this physics information. So it had The vector which is where it is on the screen the x and the y location Which is really the most important part And then all this other stuff that we weren't even using which is like cruft you're talking about like just Yeah, 90% of it was empty Just tons of physics kind of things that we aren't really using because it's too simple of a 2d body Well, these are all if any of you have ever used box 2d in another life These are all of the fields that box 2d supports for objects for physics objects and we're not using box 2d because Technically, we're not even using physics Like at this point with the game all we're doing is letting Godot handle collisions and and we're simulating the physics in a very hacky I forget which game It's it's sort of roughly cloned from but there there basically isn't any physics Like we just move the object based on the velocity whatever the distance is And detect if it hits something and then at some point we'll figure out what to do When two ships collide because right now they just kind of grind past each other Because Godot doesn't really know what to do But none of this information is important because like I said, we're not using box 2d. Sorry Yeah, right and then the so the other thing about this is the way we were Like in physically implemented this by having this code in the client and we also had the same code in the server Which you can imagine Hey, maybe we decided to like out of the client because we don't need all this physics stuff Now the server has it Maybe start sending them you get like in a weird mismatch situation So like we realized hey, this doesn't make sense. Like we need one Central location for this stuff to be like the source of truth in a way Proto is like an api for Stuff so if we think about The act of communicating between the client and the server the the proto defines an api for Like all of the fields that are available to put in the message payload But but it's it's not like json in the sense that they um json is is structured but unordered So as long as all of the fields for the most part are in the json payload It doesn't matter if it's like foo foo bar key value comma, you know rectangle square Versus rectangle square comma foo bar like That information is the same because i'm just looking for keys and values Proto buff is tightly packed binary data where like the byte order matters Yeah, so that's a really that's closer put stomp, right? That's that it's binary and that's right And so that that makes it behave more like an api in the sense that if The deserialization of that binary object on the other side is using a different api version Then byte number six might have been something before But now it's not the right value So we decode it and all of a sudden like crazy things happen, right? Like buffer over overflow or just you know, it's just nonsense garbage data We actually had that problem very early on when we were trying to do javascripty stuff and just trying to figure out How to pack the bytes the right way? And so it was like you'd send a message to the server and the server would decode it and it's like I don't know what kind of message this is because the byte order is bad And so it's like not even you know It's like sort of hierarchical in the way we've implemented it and like byte number two was already wrong And so it's like i don't know what to do here So yeah, so we were like to jason's point having this in both repos Trying to keep it in sync seemed like it was a hot mess So what did what did we do or what are we going to try to do? Yeah, so we're we're in the middle the midst of refactoring all this stuff. So I created this protobuf repo Which are we live coding right now? Is that what's about to happen? We might be we might we should probably do that we can So I think we're at a point where I'll show you what I did for the protobuf repo And then we can maybe flip over to the client server and try to yeah No, definitely because that'll be a good rehash of like the c-sharp conversion compiler and all that stuff So the protofiles are now this is the new going to be the new source of truth. They're all in one repo and we I added uh GitHub actions so the github actions are Um able to lint So the lint fails because we because we've asked some pretty ugly protobufs. I'll run a linter again You can kind of see anytime you commit this is gonna um This is gonna execute anytime you do a anytime we commit to any or anytime we commit to main to main So yeah, so like we can you know, we can have branches we can everybody can kind of work on their own But when it needs to go back to the main source of truth, it has to it should pass the linter It doesn't have to pass the linter, but it has to pass the the main branch builder the main branch builder Let's just look real quick at the um, well, I want to see the linter failure. Okay I'm gonna see the other show me show me how bad we are. It's bad man. It's bad It's batman. It's bad man. Um, oh bad man So there yeah, there's a lot of uh, little warnings like this should be suffixed and it's it's mostly like cheesy things like, um, you know Upper case versus lower case. Well, these are these are errors not warnings, sir. Well, this is what if we look at the Yeah, they are errors. So the way I lint is I use this um tool called buff And you just basically say buff lint and give it all your pros And it'll go through and it'll tell you like basically why why you suck So if anybody wants to contribute to this project, you could uh fix our linter errors A lot of these will be like 20 like 20 second fixes like use snake lower case or prefix with You know this prefixed. Yeah, and like the original protos were done in pro buff version two, right? And we're in proto buff version three for quite some time now So like in some ways like syntactically they're probably in compatibility mode Yeah, yeah, and speaking of compatibility like so the linter is just going to pop out errors and it's Probably going to keep doing that until we fix all the egliness, but um the builder The errors will continue until morale improves Exactly The builder does do a check for braking, which is going to say like between Like some of the stuff you were alluding to eric if I if I ended up like completely screwing up one of the files and Messed up the way the binary encoding was going to match to the previous version Like I reused field six again to mean something different in this new version Um, that's a braking change This step is going to check for that if this doesn't pass Then we don't even generate the the C sharp code because what this job does Is this job? Well, so what if we needed a braking change though? Ah, good question. So I did add this Manual build where you can check this box to force code gen even with braking change. Okay um And then so this is going to generate the code because in the repo I'm going to show you the github action just a second, but the the action is going to take these protos and it's going to Create these c sharp files Which look like why do why do we need c sharp files? Have you not covered that in previous stream? So c sharp. I'm sure we have but again like doesn't hurt to spend two um, yeah, so the client and the server are both using the c sharp mono version of good o and so when we send messages back and forth It's via this c sharp Um, communications library. I don't what was the name of it the library that we pulled in mqp No, no, no, no. So well, so let's be let's be careful So amqp net light is the library we're using to handle communicating with the amqp broker Yes, but on the c sharp side um So when when when we very very very first looked at it. I was like, hey cool. Good. Doe like protobuf and somebody had written a gd script implementation of protobuf file parsing and then what I was trying to do was like Load the gd script thing as a as a as a node so that I could access its functions within c sharp And it has just got hot mess ugly real fast. Wait a minute Huh, so we can instead just directly build the c sharp Well, yeah, and so what's the and then so I found like a uh, a c sharp net package That was available to The protocol buffer compilation. So so the dot protophile Is just a definition It's language agnostic and so protobuf itself is not Java it's not Dot net c sharp. It's not like idea. Oh Yeah, it's a it's a design language of sorts and then the language that you choose the actual programming language run time Needs to do the right thing to build the binary byte stream Of that represents the buffer And so this compilation step that that that jason's showing right now that does um That generates the c sharp stuff What it's doing is it's taking the protobuf as a definition and then generating c sharp code that provides an interface for Generating serializing and deserializing the actual binary buffer based on the definition and so similar to object oriented programming When you have a model that has a variable that's accessible called, you know hamburgers and it's an integer Right, you can do like model instance dot hamburgers equals seven, right? I'm setting the number of hamburgers and so what you'll see in our actual C sharp godot game code is We will create a new message object And then we will set the fields just like it's an object oriented dudad And then we call some serialization and other functions that we get From c sharp Right. Yep. That was a very long-winded explanation. That's great me. I'm like and this This is the short reason it works is that these these classes that get generated with the proto data that we gave it are Building off the core classes in that library And the nice thing is I mean it's language agnostic, right? So there's protocol buffer tooling For almost any language you can imagine at this point Because it's been around quite some time and it's been heavily supported in fact by google, right? So When we When when we built the first client against the old c++ game server That first client was phaser javascript And so we found some random proto buff javascript implementation That would load the protocol buffer definition files and then give you a javascript interface To serialize and deserialize and do all the other stuff So I guess let's look at the um The github action. Yeah, let's just check this out and then as you know as we identify if we need more language support We can throw this in here and build those as well into other folders. Yeah That's why it says generated this slash c sharp um the workflow So any of you open 3d engine developers or or java developers or unity whatever, you know if you want to you want to build an srt client Here we go Well, I guess unity c sharp, right? So we already got that covered. Yeah see fair for among other languages The um, yeah, the action is pretty pretty simple straightforward So what is a github action because not everybody might know what those are Yeah, so like if you haven't seen github actions before The idea is it can do cicd basically on actions you're taking within Github so in this case whenever on is where our trigger happens on a pull request for the branch main Or on a pull on a push for the branch main. We're going to do stuff um and That stuff could be all kinds of different things like for in this case where We're doing some checks to make sure that the the files are in here are valid and good And then we're going to do that transpile That compilation to generate um Rc sharp code we could also do things like build containers in here or push containers to container registries You can do a ton of stuff. You can nest these together all apis to do whatever. Yeah, exactly. So it's it's pretty sweet It's pretty versatile The way this one works is two different jobs in here the first one check for breaking Which you saw visualized before This uses this pre-built action called buff build So these things just set up the environment for me And then I can call and I think those those uses right those are all actually container images, aren't they? I'm not sure kind of under the covers they're they're they're github actions themselves But I believe that github actions are container images So if you like go to the github if you go to the buff build github action Page I think it talks about how it's a can it's like inside the github environment. It's it's running container images basically Yeah, yeah, maybe and but the cool thing about is that you don't even care as long as it works quick and and runs then At the end of the day you said I mean that sounds a little scary like Short stuff and it's like Like what's in that action in the in the source of buff build like, you know Is it sending our credit card information to china? But yeah Anyway, well definitely I definitely just saw a But one from some random dudes github action and I was like, you know what I'm not gonna use that one Good call who knows when that guy's gonna change it to steal my my credit card uh Not that I have a whole lot of information in my github everything's pretty much open But uh, so the next one after this passes you can see that this one Again, like says it needs that first one to pass for it to kind of keep going on and we in this one we go Um and do some dot net things so I have to pull in a version. I get to select it here So if I remember correctly the matrix statement is basically Across all of these combinations of things run the action All these times. Yeah, so if we had a matrix that included Python and javascript With specific versions it would run the gen c-sharp against all of those Versions we can do that we could do that or we could create a whole new job That's just says, you know gen python the reason I had the matrix in here is because at first I thought I was playing around with different versions of dot net to see if they were gonna Cause issues and then I just kind of simplified and said let's just stick with this first version with this Or we should probably match whatever the version is that the good dough Is using maybe so um So, yeah, let's keep scrolling down through here We might have a few minutes left. So it might not get no we got to a four. Oh nice If you want, okay. Yeah. No, let's keep going. Uh So we go through we set up dot net for version 6.0 dot x x meaning Whatever 6.0 we want we could even make this I think that that'll probably pull the newest 6.0 dot available Yeah, yep, whatever the highest version for x can be Um, we could move the x over here and make it the highest. Yeah Ruby has a similar stuff for pulling in depths where you can specify like, you know, which which important number in the nvrc You want to care about? anyway, and then Once that's set up We run this So this is a little bit different than what you guys have seen actually in the client and the server I installed this proto buff proto gen tool Locally instead of globally. I think the way you we had it in the Instructions for people who wanted to try it on their own local machines. They were installing it for like the whole machine to use In this case, we're just putting it directly in this environment that we built for dot net We already I probably only wrote it that way because i'm dumb and don't know how to do things So that was like, you know Run everything as rude to kind of, you know, hackish Yeah, just a soft protogen for everybody give everybody proto gen Uh, and then we you get everybody gets a protogen. Uh, and this is the the dot net Command that actually generates the code. It just runs that tool Tells it where that the files need to go which we saw was in the generated slash c sharp file And then if that works it keeps on going down to the next piece which is to Um push all that code to get up. So first we do a poll To make sure that just in case like anything got committed In a weird state we want to kind of get the latest of the repo so that the push the commit will actually work Um, then we add the files and then we do a commit and then we push So, I mean, I'm I'm a stupid developer and don't understand git But like if you're doing that poll after you've done the test, aren't you potentially running? Oh, but we've already done the gen so I guess it doesn't matter It still seems weird like that seems like you would end up with The c sharp next to a proto definition that you didn't actually you know It's like you've already generated it but something changed while we were generating it So we're pulling in a new proto definition and then committing the c sharp files along with proto files that we didn't actually use to generate the c sharp files You know in this case, I don't know that it really matters either way because I another Push is going to generate another get-of-action and it's going to override Yeah, but you'd end up you'd end up with a weird commit in the middle You're right. It probably doesn't matter in the grand scheme of things because we're not we're not going to tag And on tested commit you just have like this weirdo commit where It doesn't match So if anything like I would probably remove that get pull, but I don't really care Sure, we can do that. It's it's an amazing deal either way. I don't think it's Gonna make too much of a difference. So this one Does have a weird bug that I wrote up that github This is more like an annoyance than a than a bug, but It's a feature. Yeah, it this is gonna have this x if nothing's changed and you force ran it because Nothing changed and it's like there was nothing to get commit. I'll show you the actual error it gives you It's gonna be like cool everything um Everything generated and then but the generated stuff Was exactly the same so I didn't have anything to commit So I'm going to call that an error um, I think that's fine. We're probably not going to run this manually Ever Yeah I mean, maybe you could put in a flag kind of option where it's like if you're forcing it to run Without a commit like just force Commit or something. I don't know whatever. Yeah, and actually yeah, that's um, if we look at the code again Because that's what you kind of do with the um, yeah, this is this this workflow dispatch when you create this section that gives you the option to force force things Um, not just on triggers and then you can put inputs into there Yeah, so maybe we could have like a force build trigger Yeah, if you check this trigger, yeah Yeah, well because the thing is like Why would we ever want to force a build? It seems like you would only ever want to force a build to see if build itself works Not necessarily take what it built and push it back in So maybe force build would just like do the build step and then skip the push commit stuff or something I don't know. Whatever it does. Yeah, and you can make a new workflow just by calling over here and saying You know new workflow or just actually just going in here and creating a new file And putting it in there The the that's the kind of last piece. I think I want to say about like get up actions if they're new If you're new to it to create them They're you just create a folder dot github Slash workflows throw them all in here And they get integrated into your github So technically one could argue that this is get ops Because we're defining things in git and in order to change the workflows Theoretically you have to put them in git and commit them Yeah, I wonder Let's go to the live stream search. Do we have an open shift? Here we do Now we can do little ops from here deploy to our cluster Uh, yeah if the cluster had a public If we had a cluster it will we need to get a cluster Yeah, no, I know So, uh, so now we have C sharp in a Folder subfolder. Yeah So now we see sharp. We have in a folder we need to do um We want to update the client. We want to update the server so that they we get rid of the existing proto files They've got and we want to point to this git repo With a sub module with a sub module um So how do how do I do that? Or do you want to do it? I'm gonna make my do it you because I don't have I I just got a new laptop. So I don't have anything I don't have the client server working on my local method. That is a that is a lame excuse All right, so we are going to share a screen We're going to share the top screen. We're going to share that We're going to share the screen and the top screen. Okay. God only knows what's going to happen. So Let's start with the server Oh my keyboard went to sleep. Oh god, wake up Wake up bluetooth keyboard Come on you can do it Bikki wiki Oh boy Here we go got it. It woke up It goes to sleep and then it has to reconnect on bluetooth and sometimes fedora and bluetooth aren't good friends And so just it takes a very long time um Server Okay main What file has changed? Container file. What did I change? Oh, right I need to fix that. Whatever it doesn't matter. Um, okay, so let's check out a branch First we'll pull because we're good little developers Or at least we play them on tv. All right, check out two proto sub module Okay, um How the heck do I add a sub module? Get sub modules That's the internet So I think we do I think it's pretty simple. I I think we can just get a sub module add But the question is how do I tell it where to put stuff By default sub modules will add the sub project into a directory named the same as the repo You can add a different path at the end of the command if you want it to go elsewhere so First challenge I see with what we're doing is um GitHub the com red hat game dev Oh So if we look at the server file system structure Which is horrifically bad and terrible and doesn't match the client, but that's fine. This is my hack job Jason is Jason wrote most of the client. He's a much cleaner coder than I am So I've got this proto folder that has the proto files and the c-sharp files so when we do the clone we're going to end up with srt proto buffs folder generated c-sharp As the destination of the c-sharp files, which is fine. Maybe we'll we'll see how that works So from a good coding hygiene perspective, mr. Jason, I should probably Do do I want to move this folder into somewhere as well because like in the client You've got um all the networking stuff in its own folder Yeah, I like the idea and then you've even got server connection in its own folder I like the idea of living in a networking folder Okay, those are the message definitions, right? e It's the definition of anything related to networking Yeah Okay, so this is where we're going to do live coding Because it'll like it'll nest it too because when we because like you said it's got that nested structure already in the other repo Sounds good to me. All right. So our our six viewers are about to see some really terrible things Um, I don't want to file. See I've already screwed it up networking So we'll do this one one step at a time So we're going to have a networking folder and we're going to see the into networking And then we're going to do a git sub module add um this Maybe ht. We'll see It should work Maybe because I've got the ssh key. Okay, or an ssh key that works. Okay. So it did it So now the question is We don't have any tags on this and and we just have the one branch which is fine for now So if I go into srt protobufs, we see the proto files, which we actually don't need And then if I go into generated c sharp We see The c sharp files. So one Well, actually, I'm not going to ask that question yet. Okay, so At this point, I should be able to nuke the proto folder Because we're not going to use it so move to trash And now things are going to start blowing up So using red hat game dev srt Could not be found What actually defined that Originally I'm pretty sure that was in One of the c sharp proto definitions or whatever So it's all here and we're gonna open networking generated Command buffer So namespace red hat game dev srt. So the question is Why isn't It finding the um The namespace and it's also not finding the Yes, not finding any of it is basically the issue that it seems to be having right now And if we were really going to hurry doing a symbolic link would be a quick way to probably Work around yeah, but that we don't want to do that. Um, so the question is why isn't it finding This stuff Because it found them when they were just in the proto folder and now they're just it's just a few folders down So this sounds like vs code is not Loading the full path. So I'm going to do the nuclear option and I'm going to close that window And then I'm going to make a new window and then reopen The server And we'll see if it re Spill unks through everything And finds what it needs to find It has not yet spit out any errors So I think that fixed it Yeah, because I think the namespace should have been the same because the namespace was defined in the proto Yeah, the namespace is the same, but I'm sure there's some like vs code thing that says like re re inspect the entire Because that was related to like intelligence and code completion and and whatever and the cshar plugins and all that stuff So I'm sure there's like a Yeah, so at this point everything is actually working right so there's no errors This is clean mqp server or whatever So my question to you jason is what did you change at this point? I try to change almost nothing so so that wouldn't be like almost nothing's not nothing So yeah, I'm going to tell you exactly what I changed. Um, so if you go to the proto files I see them. I'm here. Um The box 2d one Um box 2d proto, okay, you'll notice I slimmed this one down a lot Oh, that is very slim just to the things that it looked like we were using Okay, in fact, I left the uuid in because I was unsure, but I'm pretty sure we don't even use that uuid because the parent Message has its own uuid You know, you might be correct So and then this body 2d is new, isn't it? So that's the one we want to switch to this is going to be like a little bit The naming is a little bit cleaner. Um, it uses vector 2d, which is the what gadoe calls it. It uses more like gadoe type terms Like rotation degrees versus angle Got it And then we can we can grow that as we need to Got it. Okay, but These are all here. So the server talking to itself with these protos should actually work should just work Stage changes sub modules and This new folder. Okay, which is weird I don't understand what it mean what this means It means that as you put a sub module in there. Yeah, okay So if I come here and we do this So for those who have been paying attention the entire time, which probably is not any of the six people that are watching Um, the serve you can basically play the game on the server by yourself Um with the debug UI so I can join a player and control that player and all the other stuff. So right now it's building the game Which it appears to have done It has loaded config, which is fine It's connected successfully to the amqp And if I come over here, we have the thing So if I join a player Did not explode If I move the player Seems like it's working velocity position hit points, etc And if I shoot It shoots sweet I was successful in not breaking everything And the game Are you back? Okay. Yeah Major meltdown as usual cool It works nice so we need to do the same thing on the client and See if I don't know if we can see if they talk to each other and then we could start taking advantage of the the newer data types and the cool thing about I think The thing I think is the coolest about all this stuff while Eric's sort of like chopping in and out Uh, is that like this is all like This is all like the hard like the CICD stuff is the stuff that like You don't think about when you're building a game It's the stuff that you need but you kind of maybe sometimes you put off or like you don't want to do it yourself Yeah, and but it like makes your life so much easier once it's all set up Like when whenever we start making changes to like the the data structures and the communication now and we have it Automatically build for us automatically updated in both the client and the server And synced up and like logged and tracked and all that stuff like that's Going to make life way easier. And I think also once we get things containerized We'll be able to run the server like we'll be able to do some of that CICD like launch new versions of the server deploy Yeah, um, what is this a stain? No, I don't want that. Oh, I see what that was doing. It's trying to Stage a change into the protobuf folder, which we don't want to do. Can you guys hear me again? It's this file That's in Protobufs, well, let's let me okay, so I've got these changes staged um switches to using submodule based protobuf Oh god Did you say oh god? I did Did you play something? Well, I I committed changes and I wasn't sure that I put them in the right place so Push to Godot You say that as if it's true and easy, but I have had some horrible I've had some horrible things happen and get sRT. Good. Oh My experience if you make a mistake you just write over it. You don't try to undo it. It's easier. That's true It can be yeah All right, we'll call that's a work in progress I'm not going to merge files change 16 Okay, so we get this protobufs folder With a specific commit which we should switch to a tag, but whatever and then we have a sub module Okay, so I'm going to leave this sitting I'm going to Build the server Oh god, how do I how do I do this? Export There we go But I need to do that from the sRT folder Let's try this So I'm running Godot's exporter from the command line and I didn't tell it to do it quietly. So it's it's going to show The UI while it does it It it worked it didn't we got the errors we expected So time stamp 315 that's now. So this is good If we run this It it did do the thing Okay Just for giggles Wow crumb, that's a lot of cpu Okay, you guys still hear me. Yep. Yep. I have turned off the I think it has to do with my crappy cpu gpu um So I minimize the window that that's showing all of you. So I see is my terminal right now Okay, so now I'm going to go to the client And I'm going to attempt to do the same thing So Oh gosh See Godot. Nope. I want the sub modules code copy. Okay. Go to vs code CD networking Get sub module add this Okay delete proto Move to trash and so how do I restart The intelligence or whatever Without restarting vs code itself. I don't know Restart intelligence for the active file debug restart container restart go restart. I'm the sharp. Yes, that's probably it I think that's the c sharp stuff But for whatever reason it seems like it it didn't need it because it never blew up And it just worked like Nothing nothing changed. No red Nice. So in theory the server is running in the background So if I try to do a build Um, it might work and I'm going to do it very quickly and I'm not going to talk because my computer's probably going to melt down So we'll see what happens. Hang on. Here we go. Go hear me. Maybe Not to put you on the spot ratty, but do you have a running client On your side I do have a running client or I don't have it actively running, but I had it running Just before I ran the stream So it it can run We try to put two clients on the server Yes, if the server is externally exposed, I could do that It worked. Whoo. Added um Hey, so that worked right So it seems to have worked. So let's see Bash We are oh god. Why are there two? What did I do? Oh, no awful, okay Get pulled from main Wait, no, right. Yes the origin main Okay, so now we're going to check out to client Create a new branch proto buff sub module Create a new branch We're going to go over here Wow, what? Don't need that Okay Stay this is that we're going to minimize you We're going to make this bigger Okay, we're going to stage all the changes Do the change Client config don't want you. I don't want to change that Okay, here goes nothing Um Oh, no, I need to commit um switches to sub module based proto buff Enter control shift p get pushed to clients my fork I did a thing And now Red Hat game dev srt. Godot clients Look at that compare and pull requests Switches to sub module based proto buff compare and pull requests Continuous integration has not been set up. Okay, so do we all agree that these two things worked? Yes Okay Doing it live That is now officially in main I can put a lgtm in there if you if you need that now it's Make it a lot of fishing like we got we got a live lgtm. So I think we're good Um change the title from whip And Merge merge. Oh, why is that whip dammit never mind too late now? Okay That is now live with sub modules. Look at that. That was a full no problem Um, I would love to show quay, but that's going to require some tom foolery here Because when quay changed to like red hat off it It broke my ability to log in from my like red hat chrome google profile. So I have to use my personal one Uh, how do I hide the bookmarks bar? You guys don't need to see my weird bookmarks although you can see them in my work So if I come back here, um, I think it's going to be trying to do a build because I set it up to build trigger on Oh, it was disabled because it blew up So the reason it's blowing up is because quay right now doesn't support setting variables on container builds And or or taking arguments or anything and if we look at the container file Oh, I have a bad feeling about this. All right. Well, I'm gonna close that for now And I'm going to close that And because this is likely to go sideways very quickly Uh container file, right? So if we look at the container file Um, the original author of this was expecting people to use this to like maybe, um Use different export presets But the server is only ever going to be exported for Linux X 11 using the container methodology So I can actually hard code this Um, so let's do bash Um, I find it faster to do this from the command line because I'm old school nerd. Um Get pull origin main Okay, so now we are good and the only files that are different are the container file What this this file, I don't understand why that's there Am I supposed to commit that this odd empty file? Okay. Um, so the first thing we're gonna do is we're gonna make a new branch There's more live coding here. So I'm gonna fix the container build You guys still with me? Hello Yeah, I'm still there. Sorry. I was on me. Yep. I was on me too Uh, gado server We're gonna create a new branch called Um hard code container build All right, so the first thing we're gonna do is fix This so that should be Source config logger.cfg. And so that should build now It's getting thundery over here. So hopefully I won't disappear. My power has been pretty stable So I think we're safe um All of the errors so far are expected. Hey look that succeeded So we got a successful build. Okay. So first step complete so When I ran that command I was passing in the What? Oh Godot project name build arg Godot project name. That's what it is. Okay um So i'm actually gonna Get rid of that We don't need this arg Don't need that We are going well actually now I can't remember what it was called So we probably need to change the name from test at some point to actually just be server Yeah, that would make sense The test is successful. It's graduated into a server Yeah, it's real. It's real now All right, is there any place else that gets used? Uh export pack. Godot export preset Uh, that's hard coded here So good I think this should build again if I try and build it again I'm gonna get rid of the build arg And it should just work so far so good Yeah, so again, um, we're only ever going to build this one way and kweta doesn't support passing the arguments. Um When you configure the build triggers So we're just working around that if we need other, um Builds we could actually just have different container files in different folders and have different contexts. Okay successfully tagged. We are in good shape So if I come over here, I'm going to add the container file Um, this is container file for quay builds We are going to push this to godot server my personal fork Um, oh no, I need to open chrome again. Sorry. This is awful What are we doing? Oh, so many browser tabs and windows. Okay Personal browser quay i o We're going to move you up top here um srt godot server Should be a new pull request I'm just gonna merge it Because it's fine. Nobody's using the container build but me us I have a lot of quay stuff I imagine the servers like once we get, you know, this thing it's like a rhythm of Of working the server will probably get continual updates and like so being containerized Like super beneficial for us to have Just to be able to continually build and roll this thing out um In sort of just as like a A general thought thing If this starts off your rhythm Eric Eric tell me to shut up. That's fine But I was thinking about before the call. I was um, I don't know if you guys download a diablo immortal like it's the mobile Yeah I was looking I was watching it start up and it was going through like its startup phase and I was like, you know what that We probably need to add some of that stuff to our Model too it goes through and it does like this flash screen, but then it does like a check for updates So the client You know, there's the assumption that the clients in fact Versions potentially because you don't control Clients typically as a as a game Architecture like we have complete control over the servers But the clients are going to be whatever version somebody downloaded whenever they downloaded it Compatibility is going to be pretty important So there's like a little bit of like a buffer window where you there's some things that you know You want to update the client, but maybe you make the decision to To like kind of push that as a dynamic update from the server so the client can receive it on startups If we built like a system where the client could go what version Do let me ask For my version. Are there any things I should pull down? And that sort of workflow Yeah, so there's two there's two types of updates So one is like a I can update myself By just downloading some content and then the other one is um, I actually need a new client Like a breaking client change that requires a new download that we should alert their user Like hey, you need to update your client before continuing like Go get a pretty Yeah, exactly. Um So yeah, well, I don't I don't know what that would look like in godotland because you've got that like binary compile. So if I um, I don't know what this is taking a long time But it's doing things. Well, I think the first step might be just adding some of that the the crawl the The getting started part it will be, you know, just get it working Pass some of that information back and forth so we can at least like make those decisions and help Compare the list of resources and maybe we have a version identifier associated with a package of resources And if the version's different or if the resources have changed Then you need to be willing as a client to accept new stuff Either as an addendum as a delta or right a new package Yeah, and so the first step is like can can godot even do that I don't know for those that are out of the box. There might be a If we look at yeah, yeah, but if I go into the folder And look at the like the server for example There's the pck file and then there's The binary But like I think most of the junk is in the binary But there's also like a zippy way to do it Yeah, I like the weapons Export does it a bit differently too, right because when you're on a web server And being hosted Like for pot escape and pot escape comes up It comes up with the image logo, but then it has this progress bar Well, actually like the pck that's generated it's downloaded to the client from the web Before the game can play right It worked we have a built Yeah, and what roddy's talking about in that case is we're for pot escape It's it was being served as web assembly. That's right true And just basically in an hdmo file On a pachi web server So here's the server that just got built The image actually works And so if I look at the info it's quay io godot server, right? podman Pull actually want to podman run instead, but let's let's do just this part Copy oh Like very excited Go to the chiropractor. Okay. I'll do that shortly Okay, um, so if we come back here Where did I run it in a container? Nope, that's because I need quotes Okay, so now we can try again podman run it rme srt mqp url equals mqp 192 168 1 2 5 2 5 6 8 2 quay io srt main Okay Trying to pull look. It's doing it. It pulled it Hooray, it did it, but it didn't work right Could not load the config the file does not exist The logger config Yeah Yep. Yep. Yep. It's the same problem we had before So since we have time we'll do some live troubleshooting. So what I want to do is Entry point bash Is that the only problem that it hacks? I mean the logger config has defaults, right? It's like not that Yeah, but the issue is that it breaks the initialization of the amqp okay Because the amqp server Tries to load the logger config and fails and then it like just stalls Oh Let's fix that Let's make it go Didn't load the logger config like I'll just stick with the defaults Oh god Definitely never work There we go There's logger.cfg Oh Hey, are we running uh Amq Artemis in the container right now too, or is it running? No, I'm just running it locally on my I could have been running in a container, but I'm not I'm just running it locally So now I got to do another container fix here. So get check out main and get origin main and Get check out here So while I'm doing this jason if you want to look at the code and see if you can figure out why Loading the logger can like blows up The initialization of amqp go for it. Okay, but I think that's going to be like lost in node tree c sharp hell land Yeah, that doesn't sound fun. No, it's unlikely to be fun to So I rebuilt it locally Hey worked look at that. All right. So let me do this. I will Oh, okay. Perfect. We're going to show some awesome CI here. So the build trigger is re-enabled And so I am going to Add the container file fix copy location of logger cfg for container build Uh, I'm going to push that to Oh, oh god. Damn it. I just committed to main Did I I did This one I checked out Okay, how do I undo the last commit? Is it reset head one nerds get hub nerds get nerds I usually do a rebase minus I head till the one and just drop it that'll drop it locally I didn't push yet. So we're good. Okay Um, what do I do here now? I don't know. I always do rebase base minus I yeah, I just did that Okay, and it it brought me to this interactive whatever. So do I pick or do I drop? Assuming that drop commit you don't want. Yeah Is my but my unchanged file is now Disappeared my changes are disappeared. Yeah, that's right I didn't want to do that. I just wanted to uncover I don't remember what I changed. It was two seconds ago Oh, there it is What I don't understand what happened And bs code would likely refresh, right? Well, this is the current file, but this is the change That I made or maybe it didn't refresh I it it definitely refreshed I would I would assume it refreshed Yeah, that's I thought that was the change that I made Let's do a good status and see what it says It's not showing it. So fixes container file for quay builds but somehow This is the last commit Which is where I Yeah, that's not and that was just in right? Yeah, so I don't I don't know what to do. It's it's in main I supposedly dropped it but it didn't do that and the Well that commit was 10 minutes ago. Wasn't it 12 minutes ago? Yeah, your computer clock there says 15 39 and that commit there was 15 27 Okay, so then what did I just change? I just changed something and committed it and I don't remember what it was So that wasn't it then? I'm so confused Hard code container build is what I did That's what I merged But this change This change was not part of hard code container build. I didn't think If you could status is there unstage change unstage change of the moment? No No, I could you can see it in the vs code Yeah, so here's where I Did something and then Undid it I think the rebase like overwrote the last commit. I don't understand what what that rebase just did It should have just dropped the commit locally So the for example, if you'd already if you were one commit ahead locally Then your upstream whatever that happened to be And if you were to then pull upstream after dropping that one commit you should be then in sync With the remote repository Well, then I don't I don't know what the hell I changed and then unchanged. Yep. Not sure This is where we added the sub module And then merged it and then this is It's the hard coding. Well, did I change But then unchanged in the container file don't understand It I swear to god, it seems like it it like squished this change into It well, okay. Here's an easy way to check Yeah, and so the latest change did help Was the merge over here number 37 Which is what you're calling is your head. I don't understand. I'm so confused. I don't understand how I Added a change to the container file committed it to main uncommitted it and somehow can't remember 30 seconds ago whatever So what was the last quay build? The last quay build was hard code container build But that image doesn't work because it doesn't that image doesn't have it Because this hard code container build Oh, it has this but it didn't Work or did it already rebuild? I'm so confused right now 1936 but where what the homo zone was that in comparison to your laptop? Yeah, so it's not It's not there In the image that's on quay despite quay having built this Oh Dot oh, okay. I okay. Got it. Got it got it brain fart. Okay Here we go It's available locally, but it's not check out to the server fix Uh container So where does the logger tfg exist at the moment? It existed in dot There we go. Okay. Let's try this again now. I see what happened So what happened? So the this was the change But I was looking at dot Oh, I see and thinking that that was the change but it wasn't All right, so it's the change was suddenly different Yeah, I had changed something. I just forgot what it was. Yeah My brain is fried. So we're just trying to basically get the I'm trying to get the container build to work. Yeah with the log file in the correct location So we we pulled these log files from the source code And In the container file we say like we want to manually take these files from the source code and put them in these specific So so good dough good dough here. Let me show the build process So when you do a good dough export See how it does this like save pack Yeah um And it So the that it has There's a weird thing with how good dough build stuff Into the pack file And in the export presets I told it To oh, I think I lost that Oh, I see. Okay different problem. Um Let me double check something here. Sorry. I'm I'm getting sidetracked, but it might it'll make sense really just trying to like Explain what's going on to the audience. Yeah. Okay. So this include filter thing. So actually let me Let me try hold on So good dough doesn't copy every single file in existence into the Into the pack file And so that's why I was having to copy it into the container But then you can tell it about stuff to explicitly include In the pack file And so I forgot that I had done that for the client, but I didn't do it for the server And so I just made that change to the export preset To tell it like include any file called cfg. Here we go. See it So now it's actually included it in the pack Nice in the correct path There we go. So I think if I run this now It might work Yeah, it did. Okay. So now it's in the pack And the logger is basically so that we can specify like the verbosity and what we want to get out from the server And then the there's another one that's for the for the networking for amq that lets us kind of specify details around that connection Well, it's the same logger config because it's the same logger used in both places Which is probably bad practice practice as well. So if we look at the server code um If we look at So it reads the file twice at the moment. Is that right? No, but there's a I guess what I've meant was there's a logger dot config And then there's also a client dot config So client. Yeah, so logger config is the configuration for the logging thing client config is where's the server and Right any other like local special stuff that might be needed. So maybe, you know in the future that would be like resolution preferences and I think it's okay for those to be separate Yeah, for sure Well defined Separate well in individual files Yep, got it. Um Why did I come back here? Because I wanted to change the container file Because we no longer need to copy The logger config. So the one change we should make is we should make the logging configuration also available the environment Because right now it it's not It's hard coded to that to that file All right, so let's try this one more time Sorry if I'm moving a little fast. Okay, that's all built expected errors And run the local host version that worked Okay, so come back here. Look at the changes Yes container file. All right. We don't need that copy anymore Change the export preset And I don't I don't understand what this protobufs diff empty file is for I'll do some google food and see if I can figure out why that's being generated auto generated that right? Well, I think it's a vs code thing because every time I hit plus it doesn't do anything And if I do a I do a git status we see this And I think that's because um I don't know Why because it's a sub module but git is showing it is on it's I don't know seems like a weird Thing you're in that server right now. Okay. Yep What branch are you on? Uh fixed container log file whatever but it it'll do it in main too So is the sub module changing that branch? So Oh, that's why then if you switch from main where the sub module existed to A different branch where the sub module didn't oh the sub modules in this branch though. Okay This branch was forked from main Oh, yeah, so it's it's just saying that it's not staged. It just means you haven't added it Although it says on track content. No, but if I try to add it doesn't add it Oh, you know, this might be a weird um sub module thing Yeah Um Like in a knit But I don't want if it's not breaking anything we can look at that later Okay, so now if I merge this to main We should see a quay build fire off Boom. Look at that. See eye, baby. Okay. That's gonna take a long time Anyway, it's probably a good stopping point. Nice We did lots of things all the all the many things It's pretty good Yeah, so what do we do today we played with protobuf we played with container builds we played with messaging We talked about exporting We talked about get sub modules compiling c sharp protobuf for godot All kinds of things So now that we have So this is the part that seems most interesting to me and I'm curious if you guys want to work on something like this next is that Now that we've got things containerized we can roll it out into like open shift and Scale it up and play with how? things well, I wouldn't it could it can't scale yet because the server has no concept of ownership and so every server would be Handling everything and sending every update about everything so you'd have two servers that we're trying to claim the same player And sending updates for the same player right to all clients So there's no point in scaling it up because it's going to be very bad. I don't mean I don't mean doing it I mean putting the plan in place to see where there's a warrior to make the next step toward scaling it up Let's design Let's start to do the design for that part so that we can kind of get a feel for what that's going to look like Yeah, and what what the concerns are that we need to separate? Uh Yeah, I mean I don't I don't think we actually need to run it in open shift to start talking about those concerns Like we can we can talk about those concerns before we ever do it you know, we could easily run it in open shift at this point because If there's a simple artemis container we can fire that up and then We can run the server in the container in open shift and tell it via environment variable about the broker And then the only other challenge would be We're not doing amqp over web socket Right, we're doing pure socket We are doing pure amqp over tcp at the moment. Yeah, so we would need Um Does it support sni or is it pure it does sni? So we could potentially put it Behind a route With hcps and then it should it should route the traffic Yep, so we could potentially get the server running And fire up a bunch of clients But what would inevitably happen is the performance issue I had where Like it slows nuts because it's sending spewing just so many messages But it's worth a try just to see even with just two clients just to get Yeah, just to get those things out there into the platform Yeah, I mean honestly like we don't know what the scalability of the game is with one server yet So we probably just want to get the performance better with like delta messaging or like selective updates or whatever and Start to do some of the client lurping and interpolation and dead reckoning Before we worry about like horizontally scaling. Yeah, that makes sense. That makes sense And then potentially start thinking about storing state Outside the server and then practice like what happens if we kill the server And then like it restarts because it should restart really fast if we kill the pod, right? It doesn't start up time on the servers like, you know, second like not even a second practically So if you nuke the server and then the server like fetched all the state From the cache or the data grid or whatever Like what would the player experience be because that's a common problem with a lot of these games Is like and who owns the server pukes Then everything's gone because the server contains all the state and it's stateless Right, but if the player data is in the cache then if a pod comes back and we understand Which player data is unclaimed by a server Then when the pod restarts the server It can claim its area of We would just need to yeah. Yeah. Well in the case of a monolithic server Where we don't have a horizontally scalable game Initially the first thing the server would do is ask the cache like please dump me all the information About all players Well, just ignore ignore ownership right like just assume single server no tendency no owner whatever So the the server would just say when it starts like hey cache like do you know about any players cool? And then it would do all the normal creation instantiation type stuff Hey, do you know about any missiles cool? And then it would do You know whatever it does and then the clients just have to be smart enough to know like oh, I already know about that player I'm just going to ignore that you're telling me to create them again You know what I mean? Yep So that'd be that'd be interesting So sounds like we got a month's worth of work for us At least Cool. All right, everyone. Well, thanks for thanks for watching. I know some of you were here the whole time I appreciate it very much and You know for those of you that joined late the whole thing will be available on twitch and youtube Um, and you can always look for more at uh, openshift.tv We'll see you next time next month. Same same bad time same bad channel. I think I hope maybe see folks. All right Cheers