 Hello, everyone, and welcome to another episode of the scalable multiplayer game design show. My name is Eric Jacobs. Joining me today are my partners in crime, Michael Clayton and Mr. Derek Reese. Eric, you're growing a beard, man. Looking good. Thanks. Starting to get a bit lumberjacky. Yeah, I mean, I'm living in Northwest. I got to look like the part. That's a bunch of Bob in the background joining us today. So yeah, what have we been up to? We didn't get to do last month because we had a lot of crazy stuff going on internally. And so we didn't we didn't get a whole lot done to actually show you, but we did get a little bit done more recently. And what we did do or what I did or what I butchered probably is more appropriate was I butchered my way through getting single sign on working. We already sort of had it a little bit with the chat lobby for the game. But what we wanted was for the web client to authenticate you or at least force you to authenticate, if you will. So what I'm going to do is show my screen here. Hey, diva 73. Thanks for joining in today. Yeah, this is the one I want to share. Share. Okay, can you all see the open shift interface? Hey, yeah, looks good. Cool. All right. So this is our open shift cluster here. We really thanks. So we've got the single sign on operator, which has deployed key cloak, Red Hat SSO and its database. We have the infinispan operator, which has deployed the game data data grid cache, which really isn't being used for anything yet. We'll get there someday. But when I run my little script, that's what it deploys. We've got the AMQ broker operator, which has deployed our message broker, which is how the game client communicates with the game server. Then we have the actual game client, which now is a true Node.js application running express, because that's how we're doing the key cloak integration. And then we have the Ruby based chat lobby. Oh, you know, if I deploy the game server, I could actually just throw this up and we could let people play the game or do like blow things up. Well, anyway, we'll maybe get to that for next show. So if I open the chat room lobby, there's no skinning on this, I should probably bootstrap it up or something. If you have a favorite web CSS framework, either you, Michael, you, Derek or any of our viewers, go ahead and put that in the chat. But anyway, so when I click the login button, it's going to direct us to single sign on. And we can skin, I think we can skin this page, because I know that the internal Red Hat one looks different. We're not using any local based authentication, we're only ever going to use GitHub for the purposes of this game, because why not, right? We're all techno computer programmer nerds. So when I log in through GitHub, if it doesn't blow up, apparently I was already authenticated enough to GitHub that single sign on sent me directly back. And so now I'm in the lobby and I can send chat messages. This will actually work. I'm going to put this in the stream chat. This isn't a permanent URL. This is just a cluster that I have for now. So it will probably go away. But if you log in with your GitHub ID and type chat messages in the box, they'll appear in here. I don't know if the scroll bar will ever appear or whatever. But anyway, what we did under the covers, hey, Mr. Clayton, there you go, test. What we did under the covers, if I inspect, if I make the text bigger, oh, it does make the inspector bigger too. So what we did, what I did was I wanted the game client to force you back to the lobby if you weren't already authenticated enough. And so one of the hacks I did, drop table spaceships, yes, exactly. One of the hacks that I did was I made this link for Play Now, a form that actually posts your encoded JWT access token. And so it posts this over to the web client. If I pull up the web client code, and Michael, I know you've made some changes. I don't have your changes here, but I have enough to just show what's going on. If I pull up app.js, this is a Node.js application it uses Express for pretty basic handling. And so when somebody posts, it runs a series of middleware handlers in order. And the first one is, okay, check SSO handler. And if we scroll down to the function, the check SSO handler does a couple things. First, it says, all right, I'm going to redirect you back to the lobby by default. If I can't figure out what to do, that's what I'm going to do. First thing it does, it says, hey, if the request has an access token in the body, you're sort of already logged in, most likely. So we're going to send you to SSO. Now, this sounds dumb, right? Why don't we just always send you to SSO? Because I wanted you to get sent back to the lobby if you weren't logged in. And so sending you to SSO, if you are already logged in, kicks you back to the game client, but doesn't actually send you away. I know that sounds really weird, but if you think about it, if you just bookmarked the game client URL and you kill their cookies and you close your browser and you went to the game client, what we don't want you to be able to do is get kicked to the login page and then immediately kick back to the game client without ever seeing the lobby. Ideally, players should start in the lobby so that we can show them notifications or if this was the real world, so that we could sell them 5,000 things with microtransactions. We definitely want them to start at the lobby. And so what this is doing is it's basically saying, okay, does the game client know anything about your session? If it does, we'll send you to double check your authentication to make sure that you're still valid, like maybe you're timed out or whatever. But if I can't figure out what's going on with you, I'm just going to shoot you back to the lobby and then let the lobby handle showing that you should really actually click the login button. So if you have an access token in your request, we don't redirect you. If the server has session data for you, then we don't redirect you. Otherwise, stuff is missing. And so we force you back to or redirect you to whatever the lobby host name is as an environment variable. So pretty simple stuff. We took all the existing code for the web client, which was basically just static HTML and JavaScript. And we moved it into the public, I moved it into the public folder. And so all that stuff lives here. From a phaser perspective, I made a couple of really minor changes. In the menu scene, there's now a quit button. So if I scroll down here, so there's a button that will appear for quit. So as soon as you come into the game client, the first thing that happens is you see the menu. And one of the menu options is now quit. And then if you click the quit button from the menu, it sends you to the slash quit path. And then if we look at the express stuff slash quit does two things. Destroy as your session, as far as the client is concerned, as far as Node.js is concerned. So destroying the session means that you're no longer going to have this key cloak data in the session. So that's good. That means that you'll get redirected next time you show up. And then it redirects you back to the lobby. It's quitting the game from the quit menu, redirects you to the lobby. There was a quit button that we had added way back when I added ugly quit button to the upper right hand corner. And that would take you to a quit scene. Probably the quit button in the menu should also take you to the quit scene, but whatever. The reason that we have this special quit scene is because once you're in the game, you have to tell the game that you're leaving the actual game like the playing field. Whereas if you're in the menu, you're not actually in the playing field yet. You haven't been initialized. So I guess we don't need this quit scene for that. Anyway, so we send this leave message via the client, which tells the game server like, I'm leaving, bye. And then we do the same thing. We just href the user back to slash quit, which destroys their session and sends them back to the lobby. I don't have a game server running. So when I click play now, it will take me to the client. The client will eventually load. I will eventually see the menu. And so if I click quit, it's going to redirect me. If I click click join, oh my God, it's going to play music. Don't do that. Don't do that. Jesus Mary. Oh, and the quit button is hidden by the zoom thing. So if I click the X now, I'm back in the lobby. But you'll notice I'm not logged out. I can still go to the lobby and do things. If I click play, it's going to take me back into the game. And then because I'm posting into the game, it's going to be like, Oh, cool. I know who you are. I'm going to force you through SSO real quick, but you're all good. So quickly turns me back around and I'm back in the game. And now I can just go and quit directly from here. Same thing. I should probably send you actually back to the lobby and not just to the host. So that's my bad. But that's what's going on now. And so if I, let me copy the link. Oh, that's a form. I can't do that. All right, let me do this. If I copy the game client link URL and no, don't do that. And then I quit. If I just try to go back to the game client now, I think it's just going to boot me back to the lobby, which it does because my session's already gone from the last time I quit and my, I didn't post any data. So it didn't redirect me because it didn't find any data to post, but I'm still logged in in terms of SSO and I still have a session in the lobby. So I can still access the lobby. If I click log out and now I try to go to the game client, I'm just going to get rebooted back to the lobby again. And if I try to access the lobby now that I'm like the actual chat room part of the lobby now that I'm logged out, this I think just boots me back to the homepage. So in theory, I'm sure there's some edge case that I haven't accounted for, but for the most part, I think this is behaving like we want it to. I don't know. What do you think, gentlemen? It seems robust enough for now at least for sure. It's robust enough for my high school programming level to not explode. Number one rule in game dev is ship it, get it in front of users. Yeah. So I was thinking there is an OpenShift cluster that the product managers maintain. I think it might be a public cluster. So I'm tempted to get this all going in that cluster and just leave it up and see what happens. I'm sure it'll be all kinds of atrociously awful and bad. There's no profanity filtering. There's nothing. I mean, it's all bad. So I don't know if that's a good idea or not. But anyway, let's see. Is there any other code that I want to show? I don't think so. Yeah. So Michael, you had wanted to try to work on showing like some player data on Facebook. It's a trap. I don't know if you want to live code that or not. Sure. Otherwise it'll be real boring. I was thinking about the camera motion because right now the camera is not locked to your own sprites. So you can move off to the corner of the screen and it's kind of weird. It seems like the camera should follow your own player. So I was thinking that we could live code that. But the player data might be even a little more useful. But either way, it's just phaser stuff and did phaser a little while ago. So I might remember. Okay. I'm trying to figure out how to stop sharing. It's like there's a body. But I can't click. Before you do that, can you go back to the lobby? Oh gosh, yeah. I'm sharing all kinds of awful things. There's your lobby, sir. Oh, but can you log in? I can log in. I'm going to try something. Are you sending empty messages or are you sending like space? Oh, that didn't work. Did you send a script tag? I did. I think it's because it's a script tag in a... Whoa. Did you send an alert? The window.open didn't work for some reason. But yeah, it's a... Yeah. So we probably need to parse HTML. Which doesn't. It doesn't sanitize HTML. So we'll need to... Should I file an issue for that? Yeah. Before we put this in front of a lot of the people, we should probably fix that. It worked for me like something message. The message came back. I wrote up on the screen and a new tab popped up. It's pretty awesome that you thought about that. I was trying to rickroll you, but it didn't work. Well, I don't know that sending me to the phasor documentation is much of a rickroll. But... Oh, did I change? Oh, I did change that. He just never wants to give you up or let you down. Definitely not. Never gonna take me around or desert me. Labels. Is there a security? I'll just call it a bug. I guess... Or is it an enhancement? I don't know. I guess it's a little bit of both. It's removing a de-hancement. Removing a de-hancement. Unintended feature. Okay. How can I stop sharing my screen? Zoom is... I'm trying to click the stop share, but it isn't actually doing it. It doesn't allow me to take over either. Oh, God. This is awful. You cannot start all the other participants sharing. If I minimize all these things, can I click you now? No. It hasn't helped me. Maybe I will just exit the Zoom. Gosh, this is awful. Turn to meeting. Aha. Stop share. Yeah. Did it. That was really frustrating. Technology. Yeah. I had to click return to meeting, which like kicked down the little menu at the top of the page or the top of my screen. And then I was able to click the button. Like for some reason, when it's hovering over the clock in Fedora, it just wouldn't... It wouldn't do the right thing. All right. You do that. I'm going to try and get the game server running on the... No. I'm not going to do that. Okay. So, so Eric, right before we started, we were looking at adding kind of a debug mode, like development mode way to bypass SSO. So you're not... Yeah. So there's a couple of different things, right? So there's bypassing SSO, so that if you're running the client locally with the server and you don't want to set up all the other things, it'd be nice if you didn't have to have KeyClick running. Yeah. Yeah. So should we do that first, you think? Yeah. Otherwise, what are you going to do? I mean, you could send me a KeyClick JSON that works. I suppose I could. But this could be a good thing to have, too. I think we want that, for sure. Okay. But don't do it... We have to figure it out, because right now NPM start is running debug or whatever. So we might need NPM debug, which actually debug... You know what I mean? Because you were attaching it to the debug. Yeah. Yeah. When it's deployed, right? Yeah. Right. Yep. I'm just going to start... I just pasted this Docker run command for the game... Come again? I think we have some connectivity issue. Eric, you sounded like a very... My back. ...fashed out robot. Yes, I think so. Uh, are you on Fedora? Fedora? Yeah. You may need to run those as Pseudo. The Docker run command? Maybe. Oh, Docker, probably not. If it was Podman, maybe. I'm just running exactly this command that's in the readme. So... Yeah, I see it. I recall there were... There's some issues with rootless and Podman. Yeah. Yeah. That's bitten me every time I've tried to use it. It's like group ID or subgroup ID or something like that relating to rootless. Okay. So you got your message broker? Yeah. That seems to be running. So I'm going to pop over here to the web client. And if we look at the package JSON, the start script is here and it's got that debug flag that you mentioned. And... What's nvim? Neo vim. It's like a modern fork of vim with a lot of the legacy stuff removed and some new capabilities added. Neo vim, huh? All right, I'm going to go look that up in the background. So this is the start script. I don't think I actually need to change that. Yeah. Usable is one of the features listed for Neo vim, just in case anyone doesn't know. A micro-regular vim, which is unusable. Absolutely. That's not fair. Somebody said that the vim key binding stuff for VSCode is now like a default extension. No way. Which is cool if it's true. It's awesome. Zoom is... It feels like everything is in syrup. Everything is so slow. I'm sharing. This feels horrible. Okay. So what we're going to do is try to make the game server, not the server, the game client launch in debug mode and have the debug mode control whether SSO is required for any of the endpoints that we might hit. Yes. So these are all vars, but I'm going to break the mold and do const, bringing the debug package and then... Isn't that... Isn't the debug package already in that bin www? Yes. Which is what loads app.js. But I'm in a different file, so I have to import it. Okay. This is just me not understanding how to JavaScript. So it's all good. So if not debug enabled... I had to look this up from the debug package. So it works something like this. You can query whether debug is enabled with the enabled function and has an optional name space. So you can enable and disable debugging on subsets of your modules, but we don't really care about that. So I'm just going to run enabled with no argument, which seems to... I don't see this in the docs, but it seems to stay... Or it seems to just be a wild card if you don't have an argument. So it'll add debug to... Or it'll check if debug... Is it just... Is it enabled anywhere kind of thing? Yeah. Yeah. So we'll take away the key cloak, middleware, and then I think the only other places... Tell me if this is right. The only other places that it's used are here and here. It's just a list of handlers. Yeah. These two. Okay. Yep. Yep. So we can do something a little fancy. It might not be as readable. Like this is really... Or two, like... If not enabled... Or two, hacking the NRA. Yeah. Yeah. We can use the... We should be able to use the spread operator to take away these function arguments. Yeah. So let's try this. And you can tell me, Eric, if this is too unreadable. But I'm gonna pull those function arguments out and put them in an array. Call that middlewares. And we don't have prettier on this repo. So I'll have to format this by hand, like a caveman. Okay. And then this might be a little unreadable, but let's just try it. Okay. So I'm gonna put debug.enabled. If debug is enabled, then I'm gonna put undefined here. And if it's not enabled, if debug is disconnected, then we have the check SSO handler. So what happens if you have two... I guess we're gonna find out what happens if undefined is listed as a middleware. Express does not like that, which is why here we can do a filter and this is a super short hand for just saying if the thing... If each thing in the array, or for each element in the array, if it's truthy, keep it. If it's falsey, drop it. Okay. And undefined is falsey? Yes. Yeah. Undefined, zero, empty string, null, void. Anything else? I think empty array is truthy. I forget. Anyway... This is why I could never be programmed, because you actually have to know programming things. I don't know if these are programming things. These are just weird esoteric JavaScript... Sounds programming to me. All right. So we'll log that so we can take a look and see if the array looks right. And then the way that we'd actually use it is with the spread operator middlewares. So that should give us one, two, three, four middleware functions. We should get four middleware functions when we're not in debug mode and when we are in debug mode, it should be just the slash and... Oh wait, sorry. Four arguments when we're not in debug mode and when we are in debug mode, we should get two, just the slash and the single index handler. Back, Eric. I think so. Oh yeah, sounds good. So I'll put that spread operator in the changes comments. Post. So get in post. All right. Save that. And I guess let's start it. Let's see what happens. All right. There's the log for middlewares with the slash and then one function, the anonymous function here. Yeah, because you're in debug mode. Looks good. So if you visit yourself locally. Yeah. I want to just try it real quick without debug mode and see. Yep. Got them all. Cool. So the reason I was using debug mode is because Express doesn't log anything otherwise. And so it'd be nice if we log the requests or whatever, but it's fine. We don't have to do it now. Yeah, this is, it's nice. I never, I've never seen that debug package before, but it seems pretty cool. Pretty flexible. And we can probably get more specific with the way that we're debugging. Oh, it looks like, remember how you were, you were saying when it was my app colon start didn't do anything? Yes. It looks like it would be SRT dash web dash client colon star. If you look at the last log message. Yeah, let's try that SRT web client. So that won't log out. Now we won't log all that weird express stuff. Yeah. And let's see. One other, one other thing maybe we can do is this, this port 8,000 would be nice if you could actually click on it. That's hideous. It's because it's IPv6. Yeah, but it's listening. I mean, it's still bound to, let's just do, remove that log. And we don't have to keep that. It's just, it's handy. Yeah, it's good. You, you could do it with the debug flag. If you're debugging, then you output the, but it didn't look like it. Yeah, I'm still getting redirected. Stuff is missing. Missing stuff redirected. Well, so, but you're, you, you shouldn't be in there. So we lost the console log of middlewares. Yeah. When you started the server. Put that back. Oh, SRT web client colon star didn't work. So it looks like debug is now the way that it's being enabled because it's not purely star. You may have to change what you're looking for with your debug enabled comment because it's, I'm assuming that this is now namespaced or something. Yeah, that's a good, let's try that. So I'll just add it to this debug enabled debug enabled is false. Yeah. So try it with a namespace though, like of SRT web client. False. Is it supposed to? Oh, hang on. What is that saying? It was just, it was right there. Where, where it was like foo debug equals foo. Note the calling enable completely overrides the previously set debug variable. Yeah, this is enabled, not enabled, but they got it of similar. You can set, you can enable debug dynamically by calling the enable method. And then the example is calling the enabled method. Well, I think, yeah, I don't think they actually called the enable method. They required and then they don't. Yeah, it's not, it's not Robotic again. We're accidentally turning this into a session on Foley on Linux on a Foley recording sound effects. Switch back to star. It's noisy, but it's okay. We can at least see the calls to quit and whatever it might be. So we got past SSO. I guess the next thing is we find out if we can actually connect to the server here. Oh, that's convenient. Key click integration is disabled. You have the server running? Yeah, I started it before we did anything else. Key click integration is disabled. And it probably is dead. Doesn't look like it. It won't. The server tends to seg fault if it runs for a long time without anybody doing anything with it. But there's no seg fault. That's not the server. That's This is SRT game server. That's AMQP. That's not the game server. Artemis is just the messaging. Okay. How do I run? You got to build it. Debugging and running the code made it sound like this is how you run the game server. Yeah, but if you look step three, step two is go to the debug tab. Step three was click the play button for launch main. Assuming you're using VS code. Go to the debug tab in what? In VS code. In VS code. Okay. These instructions assume that you're using VS code. The instructions are bad. It's fine. Like I'm not, you're not doing anything wrong. They're just unclear. So what does launch main do? It runs the debug in VS code. But you can't do that because you couldn't install the box 2D dependencies. You're going to have to build. Is this how you run the game server? That would build the image. How about I try this? And then you can do the quick and dirty. Yeah. So once you've built it, do you have pod man? Oh, well, you're running Artemis with Docker, not pod man. Get to pull the image again. Hooray. I think I still have disk space. I feel like we have a subtitle on our stream that's like also learn getting pod man and Docker on your local system. Just learn, learn all the things. If you watch this show, you will learn something about everything. This is the everything show now. But everything about nothing. You will, you'll learn, you'll learn everything about nothing or you'll learn nothing about everything. Something about everything, but you won't learn everything about anything. That's my favorite. Okay. Did you, did you build the, okay, but did you build the image yet? I copied the command that's in the read me. Did you, did you build the image yet? Have you run an image? I have no idea what that means. I, it says, do you know, do you, do you know, do you know how to container? So you have to do the build step up there to actually build the server into an image first run doesn't build it for you. Right. So, so, okay. Here's the challenge. So you have, hang on, hang on. You've got Artemis, which is the message broker, which is not the game server, but in order for the game server to do anything, it needs the message broker. So what these instructions are attempting to do are telling first get the message broker running, then build the game server container image. If you want to run it in a container, then run the container image. So there, the steps are out of order and this command and then I do this command and then I do this. Correct. Okay. Yes. All right. Let's do that. Okay. This is what I always hit. How do I fix it? I have no idea. I don't even know. I've never seen this error on Fedora before, so I don't, I don't know if you want to do all these things with Docker, you probably can without any of the Pseudos. So anyway, so just get rid of Pseudo and get rid of Podban and just do it as Docker, but I don't, that sounds like a misconfiguration in your system. Unknown flag. This is, I mean, we can go to the GitHub issue, but there's a Podman issue for this exact thing. Yeah, I know that error. I've never run it myself. Yeah. I've never seen it either. So Docker doesn't work. VFlag. Specified mapping includes the user ID. Oh, okay. Go, go to your, just edit that file, edit sub, sub UID and then show me what your actual user ID is. Like just do an ID on the command line. You are 21. So make sure that, so just add a zero to Mclayton. Like it's set for 10,000 right now. Actually, just make it 50,000 and that'll fix the problem for you. Because what it's telling you is that your current user's ID is in the list of sub UIDs. So if you just change the list of sub UIDs so that it doesn't include your UID, which is 21, 111. So just make that a five and then save that file. What is the sub UID file for? I couldn't tell you. My guess is that it has to do with rootless Podman and name spacing. I'm going to come find you. So don't reboot before you change that file back. Did it say it again? No, it's a different file. It's sub UID and sub GID both have this issue. Yeah. So hopefully you don't have to actually log out and log in to make it work. Hey, I fixed it. I interneted it. I did a thing. I think somewhere in the issue thread about this, it says don't edit those files. Well, make sure you change them back. As soon as you get done with running this stuff, go ahead and change it back. No event for Fedora budget to spend two. Interesting. It's been a while. Do we have the image in quay already? We might. Here we go. This is my reminder. Mildly amusing kind of watching these manual steps when Docker compose just works flawlessly. Or at least those for me works on my machine. So we have the server image in the way. Why are we not using that? I'm using it. I'm lazy, man. I can't pod man all day. I told you to just sub the pod band commands for Docker, but you wanted to fix the GID and break your system instead. I did. I changed pod man to Docker and it didn't work. Yeah, I don't know why Docker's broken. It said Docker does not have a dash V flag. I guess as an argument, that's interesting. No, it said it didn't have a V flag at all. So because when we do the build, we're doing it by mounting the files into the container as it's being built. And I don't know that Docker build supports doing that. I would think that it does. I don't know much beyond that. Oh, no, volume mounting on command line with arguments works both on pod man and Docker. I'm just trying to remember if it's the same. It may be a different syntax. Yeah, it's like one of those places I think where they like redid how it works in Docker recently or something. I don't have Docker installed on my system. So I can't run that. You could try running his compose on the side if you want to see which one gets there faster. Is it in the read me or no? I don't know. Derek's the one that made it. So ask him. I hope I put it in the read me. God, I'd be a real jerk if I had its support without putting it in the read me. Not in the read me. Not in the read me. I'm terrible. I'm so sorry. Is it not? Is it something as simple as just Docker compose and it finds the file for you or Yeah, it's just you run Docker compose up dash D. That's it. Like this. Yep. Did you put a dash in there? Yeah, it needs to be a Docker dash. Docker dash compose. Yeah, so I have that. Do I? I guess I do. Yeah, it runs everything automatically for you builds it and then sets up the network. All that junk. Probably going to have if you run at this space, we're going to have some port conflicts, I think, but you're running Artemis with podman. So it's a different network space altogether. Yeah, but it's still bound to report was it three, nine or nobody. No, it's doing the same thing I did before where it tries to pull packages and there's some comment about budget only you're using. I don't even know what would fix it, but you're on Fedora 33 34 on 34. I thought I was on 34. Oh, I'm on 33. How am I still on 33? Jeez, screwed. Finished building. So let's try to start. Yeah, you're on 34 and you can't get the right box 2D. Oh, we're still using an ancient one. I think there was more than just box 2D, but that was the one that I stuck out. If anybody who's watching knows how to write C, we could use some help. We could use some help in the C plus plus arena. Maybe it was just box 2D because that's the only one in this list that has a fixed version. Oh, I don't have a key cloak. Jason on this machine. That's silly. Michael Clayton, can you push your changes on the web client to a branch? Yeah. Oh, yeah, the logs for this are very wide. Okay. You can barely write English. Xanax, I don't know if writing English is as important as writing code. I think many of us can. I can't even speak English right now. What are words? Okay, yeah, let me go ahead and push that so you can get it there. It's because editor config is there. Okay, whatever. I'll try to just push the changes that matter. While you're doing cool get things. Should I push straight to the branch or do a pull request? You can push straight to a branch. I would think that we only need to do PRs when we're trying to put stuff into main. That's what he was asking if you should just push the master or do a pull request. Do a pull request. No, no, no. Push it to a branch until we decide that we're done with it. Yeah, we don't want to break this if necessary. We're not exactly at a point where we really have to worry too much about it being broken. I really would love to get it to a point where it's running on a public cluster and just like people just fly around all day and bump into each other and that's all you can do. That'd be great. If we had like 30 people fly around at some point, I'd be like so ecstatic. The branch is debug-bypass-sso. Cool. I think I got, I think everything else is just auto formatting noise. Oh, shoot, I did miss one. I have no idea what he's doing right now. It's git and it's cool, but I couldn't tell you. That's a dash p patch add. Yeah, basically he's adding things in portions to get in staging. No, I know. I know. Yeah, instead of whole files. Yeah, git add dash ip is pretty much all I ever do because the way I code, I'm just all over the place until I finally figure out that things are the way I want them. Then I have to break it in. Just clump around until something works and then commit 15 files. I did it. What's the dash i for, Derek? I don't remember. It's for interesting. Yeah. And impressive. Add missed files. Now it should all be there. And now what is going on with this? Serve name not supported for AI sock type connect to 10802. Where is, are you still running our Temis with pod man? Yes. Yeah, it was pod man. All right. Well, if you do that again, oh, shit. Well, now it's going to get a new IP address. So you got to do that inspect again. You got to do what? Inspect the pod man inspect command that exports the broker IP address into a variable. Every time you restart the pod man container, it gets a different IP address. Oh, that's embedded in this command. Wait. So it's, it's two commands in a box. Okay. I thought they were, it was a continuation. Okay. So let's do 803. It looks like it did the same thing though. I don't understand what that serve name not supported means. I've never seen that before. Is this, did he get the wrong port or is this something else? I got to put the server code. It looks like there's one too many things in there. Open, recent. That port is hard coded. Lost in your sort of command wrap broker IP TCP 5672 IT RM quay. I mean, that looks correct. I've just never seen that error before. And I don't, I don't even understand it serve name not supported for AI sock type. So one of them is running a sudo. The other one isn't, is that No, because again, Docker and pod man, well, I don't think anything's running in your, in your Docker because that the compose blew up. But they have completely different network name spaces anyway. That error is coming from proton, but I don't understand what it means serve name not supported for AI sock type problem is with the call, it expects port to be the second parameter and to be an integer. And you're using the latest main or whatever. Pretty sure I pulled before we did this. Try. Yeah, eight weeks ago. I have the latest code to see me configuration video studio containerization TCP broker 5672 where where did it blow up again? blew up on after fixture density. It's just not clear where it so it didn't even get to setting up the server. Did it, or did it say that space for initializing server, configuration. Alright, initializing configuration. It prints out all that stuff. No, it did log all of it and try to adding sudo to the game server pod man run command. And it has the same error still a proton container. I just want to do some phasor. Well, this this is your opportunity to make it do something without the game server. Yeah, it has to do with the connection between the proton client and the server. But this we've had this working before. So I don't really understand what the problem is. Configure broker URI. Oh, it's missing the port. Even though it's there in your run command. Oh, God, I know what that's going to do. I don't know. The latest image was pushed away two months ago. So who knows, I get lucky. Well, the latest commit to this repo was two months ago as well. So maybe it's fine. Fingers crossed. How about that? Same error of a Docker feature parity. Yeah, right. Right. Exactly. But look at look at look at the exact statement. SRT game server been broker URI TCP colon slash slash space no comma. Like that just looks wrong. What? You don't have the run command. I'm looking at your screen. I'm reading from your screen executing entry point exact home. Oh, in the logs. Yeah. Yeah. So that's how did broker IP get to maybe the cuts are messed up? I think you have some copy paste problems that are causing your issues. That's what I was saying where like you have the same you have the same thing listed twice. I don't I don't know if you can blame this one on me. I wasn't blaming it on you. I just said there's copy paste issues. I didn't I didn't say they were your fault or anyone's fault. I just that that appears to be the source of the problem. I feel like the source of the problem is this these cuts are not returning what they're supposed to return because that's where it's possible that so you're on a different version of Fedora. So it's possible that the pod man inspect doesn't give the same output any longer. So if you just get rid of everything and just do the graph of the IP address secondary IP addresses. So there you go. That's new. So there's probably in the I don't know if you can ask Docker inspect for a different type of output like JSON path or something. Let's see pod man inspect put a put quotes around IP addresses or IP address and it should be okay. Or you could just stop using the environment variable and just type in the IP address. But pod man doesn't have that particular problem. So pod man gets to the correct IP addresses. But it's getting it twice. And so that's what's your you're still going to have a problem because you're exporting to IP addresses and a carriage return into just stop trying to set the environment variable. Just go to your command and change dollar broker IP to 10807. I had one. Oh god. I could just fix it. That's another option. I'll fix it while you while you do whatever it was that you wanted to do that sideline just for an hour. Happy little accidents. Yeah. Truth driller. You know it. And I suppose I need to point the game client at the broker URI or is that JSON because if it's JSON, we can pipe it into JQ. Oh baby. It is JSON. I love JQ. It is JSON. Now I just have to figure out where it is. I wish there was a cool tool where you could like paste JSON in and then like click on something and it would give you the JSON path. I feel like there is a plugin I've used for that before. I can't recall it off my head. Cool. I'm almost there. Broker endpoint. That's what I need to change. Right. Sorry. I'm not looking at your screen. Hold on. It's pointing. Yes. AWS. Right. That's not your LB, sir. Network settings. Okay. Yeah. Yeah. Oh, okay. JQ. How do I not have quotes? JQ-R. Yeah. Okay. I'm going to fix the read me. I think the game client is connected, but where's my ship? Go look at the server logs. Oh, you don't have enough verbosity. Unexpected type. Oh my God. I've never seen that before. You're doing an awesome job of breaking all the things. Usually it's me. Strive to impress. Just following orders, sir. How do I change verbosity? Let me look at the thing to see if it actually will do what we want. I don't think anybody's run it in a container in a while because I don't think the entry point takes a verbosity flag and I've only run it locally. Hang on. Entry point. Yeah. What does your run command look like? Yeah. We'd have to mount the config file into the volume and I don't know how to do that. No. There we go. CMD-V log level. Add a dash E. So go to just before dash IT. Okay. Dash E. Capital log underscore level. Yeah. Space capital log underscore level. Like this. Equals to put in quotes. Two in quotes. See what happens. Nope. Standard error verbosity is still zero. And we still got the app. Nothing. We didn't change anything on the client side from the last time this worked. Does this run for you? Maybe you can share and we can make some progress. I'm working on it. I'm slowly, slowly trying to get us there. But when I try to run the game client, my laptop craters even harder. Let me see if I can get this running here. CMD-V log level. That should be if I can even run it locally. Studio code running. Containerization broker. Oh, I found a cool JQ that'll fix our IP address problem. So I'm just going to put that in the read me. Interesting. When was the last time you pulled code the game server? Six minutes ago. The last push was in eight weeks ago by Derek. Interesting. I know my server is doing something weird. Local host. That's why my server is doing something weird. Oh, you're using the Clio one, not the one that you built locally, right? I think so. That's the one that's in the read me. Yeah, that's probably why you're having weird issues. Hold on a second. I think maybe not. I don't have the client running locally. So I need to get that going. New window, file, open recent, SRT web client. Did this AMQP game client module come from? Where did this come from? We wrote it. Okay. For this project. Cool. I was just looking for, searching for docs online. I figured it came from an AMQP npm package or something. But that explains why I don't find anything. I was just going to look around at the binary slash map thing. How about not? So I'm not getting that error, but I'm not getting a ship either. Yeah. I'm not. I'm not getting a ship anymore on my local. Oh, I didn't change my web socket. Hold on. I gotta fix my web socket connection. I just have that set to localhost 5672. Yep. Yeah. No, I just have to actually change it fig.yaml. I know it's here somewhere. I kind of not find it. Where's the config file for the web socket? Uh, config.js inside public JavaScripts. Why is it in there? That's a weird place. I have to restart the server when I do that. Probably. Oh, no, it's a public file. It's tab muted. Okay. It's server. Yeah. Unexpected type want binary got mapped. That's new. I don't know why that would be happening. So let's do something interesting. I'm going to stop my server. I'm going to check out something very old. Would you like to share while going through that? Oh, sure. This is really going to melt my machine down for sure. I can no question. All right. What was the last beginnings of a quit button? Add keyboard driven buttons to the main scene. Great. I'm not functional. Start to build out a HUD. Okay. So I think I can check out this commit. I do have a new error message consumer.c++ unexpected type want binary got mapped. Yeah. That's the one we all got. We're hitting. Yeah. Here is the old thing. source config.js endpoint host 5672 npm start. Who broke the bill? We're about to find out. Probably me. Okay. So it works before we switch to express. So my guess is that something in express has broken the way the message communication works. Because I have seen my player. That all worked. I didn't get that binary thing. So heaven help me if I can figure out what on earth could possibly be wrong here. Let me do one more other thing here. Check out. Are we still master or main? No, we're still master. All right. Did my did my JWT? I thought we cherry picked my. This is weird. My branch is behind. I see what I did. I hadn't updated from anyway. No worries. All right. NPM start. Local host 8000. This is going to break because I don't have your changes. I was trying to figure out if your changes broke it. If that makes any sense. Like the things you did. But I don't know that I actually ran it with a server after I did the express stuff. So let me hack something really fast here. App JS. So I'm just going to get rid of these things. That should work. Restart you. All right. So that's working. Player identity. All right. So that's working. Let me run the server again. Actually, let me run it. That was supposed to do something different. Standard error verbosity arguments. Is it not? Oh, I think I know why. It's not an environment variable. Let's try for the Docker file. Entry point, whatever. Command dash v log level. Does it not work? Oh, because I put it in the wrong place. Executing entry point. Exec SRT bin entry point. SRT bin. SRT game server bin. Different. I'm trying to figure out why the entry point and command is not actually doing SRT bin entry point. Container build bin entry point. Container build bin entry point. Right. SRT bin entry point. Okay. So it's running the entry point. Exec executable. Where does the executable come from? There's the executable name. Executable all measure name. This is one of these nuances of command versus entry point and Docker that I don't understand. What's the question about the nuances between the two? So in the Docker file, we have that we use this entry point, and then we also have command. Yeah. So it appears that. Go ahead. So entry point is how you get into the application right? Command gets appended to that. So. But it's not, it doesn't appear to be being appended. It should allow you to swap the command that you're running. Like if you're on the CLI and you override the command, like that's the part that gets swapped. This should be passed in as the CMD, right? This dollar at. Yeah. Don't the arguments for CMD need to be in quotes? I've always seen them in quotes. Okay. But if you look at this argument, it's dollar log level, which should be an end var, right? And even though I'm setting an end var with dollar E log level equals, it doesn't appear to be doing anything or passing it in. And the echo isn't showing anything either, right? So here's the executing entry point. Here's the exec that it says it's doing. But if we look at the entry point, it's supposed to be showing. So it should at least have a dash V, shouldn't it? Well, all I'm saying is every time I've seen CMD, inside that array, each individual item has double quotes around it. Like the dash V would be quote, dash V quote. That's the way I've seen it. Again, I'm not a Docker guy. I don't know what, I don't know what's what. I don't think it matters. I did see a V in the console output on the next line by itself. Uh, this thing? Yeah. I don't know that that's... Oh, that's a verbosity probably. That's probably the coincidence. So why... I think this is just the output of... Yeah, right, correct, correct, correct. Yes, that's the output of the logging library that we're using. I mean, I can always just override the whole entry point. You shouldn't have to override the entry point. You should just be able to override the command. Yes, it should be dash change CMD, I think. Not that I can tell. So you do like dash dash change and then space and CMD equals... No, no. Podman run options image command arg. So you should just be able to append it at the end, but it didn't work either. So here's my dash v6. Oh, the podman docs don't even cover the proper way. Like it has a piece on entry point, but it doesn't have a piece on command because I guess they assume... Right, because because at the last thing in the run statement is command. Like if you look at the help output of the podman command, podman run options image command arg. Just by putting something at the end, you should be running command. So if I just put bash here, it's going to fail because I'm not overriding the entry point. But if you look, again, like if we're exacting some kind of command or whatever, it's just not doing that. Yeah, like I give up. It works fine with the Docker. I just, I didn't have it working with podman. Roddy tested that. Interesting. I didn't even get to join at all. Oh, because I, sorry. Sorry, sorry, sorry. Web client. I have to change my config.js again. So this is going to probably be some horrifically ugly, like JavaScripty problem that is probably going to be way above my pay grade to fix the same problem. So let's go to verbosity eight, which I think does like crazy command debug dumps, not even there. Message consumer CPP 120. So let's go to message consumer. Oh, great. Thanks. Yes, I realize that that's, I think this is going to be even before we're logging anything. Because I had added a ton of log messages for like receiving joining stuff, but that might actually be before this even happens. Message consumer, but have to add more log messages here and then rebuild the container. The question is, where is it having the problem unexpected type? Yeah. So something weird is going on with the AMQP library when it's being loaded this way. But like, I don't think we've changed any of the stuff in here. And so this is where the conversion that Jared had done to, this isn't TypeScript, whatever, whatever this formatting or way of doing things is called. Like, I have no idea how to debug JavaScript at this level, because I don't know how to like in the console get into any of these things. Because maybe one of you can explain to me a breakpoint where you want it to stop. Yeah, you can add the breakpoint and then launch the application with like the debug and then use the debug ports on Chrome. We can make sure that works. I have no idea what you just said. You said set breakpoints in VS code or set breakpoints in the browser? In the browser, in Chrome DevTools. I use VS code. Man's message consumer, that's in server, CPP. Yeah. So the only difference in, like I don't know that there's any difference in any of the messaging code. But when I checked out prior to express and ran it, like it worked fine. So something has changed in the way that the messaging code is being loaded, executed, used, wrapped, like I'm out of my league here in JavaScript land. Like I don't even know how to begin troubleshooting. So I'm all for ideas. Open Chrome DevTools and go to the game and go to the sources tab. Hang on. I'm going to move it to the side. And from sources, you can hit control P and you can, yeah, you can get to it just by navigating through the tree too. So that this isn't, it's not that this is the problem. It's like, I don't actually know what to do. Like, okay, yeah, great. I can add a breakpoint, like a breakpoint to do what? We're looking for, is that initial point where the AMBQ library is loaded and sends that first set of communications? Well, so the library is not what sending the first set of communication. This is what we're doing when we go into the game, I guess. So I guess I probably want to debug here. Yeah. I'll just start somewhere. Did I just add a breakpoint? Yeah. Right. Let's see what we got here. And then over on the right under scope, you'll see all of the variables that are currently in scope. Yeah. And then if I want to, yeah, I think I want to step over. Let's see. So what is our SCB join buffer? I mean, that looks right. That's a UN data array binary string. QP message equals this RIA message. Okay. That looks good. Like none of that's changed. Body is that. So body. Yep. Right. I mean, this all looks good. Okay. Now at that point did the server complain? The server wasn't even running. Well, definitely didn't complain. Definitely did not complain. Just unwind the stack a little bit, run that function again. I wonder if that would work. So this is where it said it was supposed to have sent something, but it didn't appear to send anything. It's async and I don't know if that is async, right? The send function there. I have no idea. I would assume so. But I mean, there's the error, but none of this code has changed. Like this file was simply moved from one location to another one. And now it doesn't work. Like none of these, none of these files changed. This code is identical. But it doesn't work when it's loaded this way. And it works when it's not, when it's not using express. Is it like a weird dependency thing or something's breaking in that send function? The browser doesn't think anything's broken. Oh, you know what? Hang on. I have a very weird idea. I bet the proto buff files changed. No, because the proto buffs, we're not using the binary outputs. We're using the dot proto files, which have not changed, I don't think. Yeah, the proto files have not changed. No, I mean, if we look at that error message, though, it's like, was it expecting a binary got a map? Yes. Yeah. So something is changing the behavior of what is being sent. Why is it expecting a binary if what being sent is a map? Like that's what you logged in the, in the Chrome DevTools, right? Was that it has a map? And that's what's in the body. Was this something where it was failing before and we didn't notice now working? No, because I just, I, if I, I did it 10 minutes ago, I reverted the code to prior to switching to express. Right. And it works. I saw that. So line 97 of AMPQ or AMQP game client, right? Where we had the, right, where we had the break. Right. Was that body maybe not working previously and now it works? Like we were sending a, you know, this dot center dot send and body was just false. And now that it's populated with data, it's not working. If it wasn't populated with data, the game never would have worked. Okay. So that, that line was required to function to make the rest of the game. Yeah. This is, this is the, this is high. I am a player. I am joining the game message. And so if it wasn't working before, you never would have gotten a picture of your player or anything. So what I can do is like, I can revert the code, run this again, and then we can look at it. Yeah. And we can set the break point here and look at what's in the thing and then like compare the two things, but let's see. So web client. And this might be a wild goose chase, but the only thing I can think of, because you've validated that that's a map being sent and why is it expecting a binary? You know what I mean? It doesn't, it doesn't add up. Like, why are we expecting a binary for sending a map? I mean, we should be sending a binary. Wait, why? You just showed in the Chrome DevTools that you're sending a map, right? At that break point, you're just a giant map of data. Nothing has changed in the code. So we were always sending a binary. We were always expecting a button. Wait, we're sending a map now. So just show that to me. Let me, let me, let me do the thing that I said I was going to do. Okay. So let's check out. All right. So this is loading. I will go to the source. I will go to the game client. I will set a break point on this sender send body. I will join the game. We will hit the break point and we see that body is this thing. Okay. So where's the binary, or not binary, but where's the data that is being sent that we're expecting that isn't matching up? Like, what does it look like? It looks like this one is working. Okay. And there's zero difference between that and what we're looking at with the rewriting. I mean, is there a way that I can like copy this whole object? Okay. Copy this object. I want, I literally just want a web diff. Is this it? Okay. So if I copy the object, this is all I get. Type code and content. Okay. If I then want to stop, why is there not a stop? I guess we're already stopped. Anyway, so now if I go back to this and then I need to change my config again, unless this is some weird like local hosty protocol-y problem, that'd be my, that's gotta be it. It's like some weird, let me try something different here. What's the broker IP address? 10805. Just for giggles. Just because I'm insane. I've seen weird problems with local host before. All right. So now we do cost 8,000. That's the thing. Pull up the JavaScripts and the AMQP client. Okay. We already have the break point on that. So when we do the thing, so much for bypass SSO. Is it not doing the right thing? Debug is false. Line 3 of that config.jse you have up? Yeah, that's not related. Okay. Oh, is it npm debug or something? Michael, no, you have debug star. Didn't you add output to like show the middlewares or whatever? Michael, you're talking. Oh, my bad. Yeah, I removed that. Okay. Well, it doesn't, it's not working. Like it, it's redirecting me. Okay. Try npm start again and make sure in the DevTools network tab you have bypassed cache or disabled cache checked. In the DevTools network tab, but that's not disabled cache? Yeah, never refresh. Okay. I don't, I don't think that's the issue, but we'll see. Okay. I think that's the issue. Yeah. Well, you do that or something else, but yes, or maybe it was that. So they're definitely different, but most of that is going to be the UUID. So if you look at the first seven lines, so it's just differences in the, the bytes after. So the first seven bytes are the same, which makes sense because the UUIDs are different, right? There should be a UUID in here somewhere. Crazy also theory. If we updated a dependency to the default change on the encoding, because in Java, updated a dependency, none of, none of this code has any dependencies or changes. Okay. So like other than express, low, like giving you the browser endpoint, everything else is identical. So like no JS and no JS's dependencies play no part in what's happening here because all we're doing is loading files. So all of these files, 100% of everything in JavaScripts and, and lib and scenes and model and everything, these files all existed previously and, and did not change. Can you step through that function, the send function to identify the point where? So step into? Yeah. I kind of want to follow body and see where it gets transformed into straight up binary data that gets sent. So this is, this is where we're in. So now we're in Ria, which is what's sending stuff. That line right there, message.encode, should encode it into binary format. So you want to step over or step into? Step over, because payload at this point should now be, yeah, just binary data. Huh. So why is it saying that's a map? Express doesn't like do it. It shouldn't do any interception of anything. It's not this, this is going, this is going directly from our browser to the message broker. Yeah. Unexpected type one, binary got map. So I like, I, I don't even know, maybe did I change files? I don't think I did. I think all I did was move them. So this is adding the app.js. This is the bin www. This is some weird, oh, this is the requirements file script that Michael had suggested. I don't think we needed anymore. I'm not sure. Oh, you know what? I think you're right. Hang on. You might be right here. So I think we are using different versions of stuff, SRT web client, SRT game server, SRT web client. So if we look at package.json, bodash, phaser, protobufs, RIA, et cetera are now in here and they get copied in. And so if I get blog, so this is probably a bug in newer versions of something. Cherry pick migrate to express, express. Aha. Okay. Good call. I don't, I think that might have been you, Derek. Copy, get reset hard head, get checkout, whatever. Okay. And so these are dependencies, but they're not, no, we are loading them in directory, no notify. And then if I look at source, index HTML, we load node modules, node modules, node modules, node modules. So we're loading protobuf, uid, phaser, and lodash. And then we're pulling RIA from network. Okay. So if I look at RIA, is there a version in here anywhere? Son of a bitch. Why do they not put versions and stuff? How do I figure out what version of RIA this is? No. Definitely not what I wanted to do. Let me look at this. So I think what has happened is there's some dependency version change, SRT web client. And so if we look at packet node, this is, we want to look at debug bypass SSO package.json. So RIA 1024. So my guess is that the RIA library has changed. So I might just have to go backwards through time until I find a RIA library that works. Because if I look at package.json here, phasers 352, phasers 352, protobuf is 6.10.2, protobuf is 6.10.2, RIA is 1024. Nope, that's the same. So we have, ah, interesting. So RIA is listed as a dependency in package.json here. But if we look at index.html, we're loading RIA from network, not from node modules. So the RIA that we were using way back here isn't actually even this RIA. It's some other version of RIA. Whatever version we pasted into the repo. It's whatever version this file is. And so I'm not really even sure other than like downloading each tagged version and diffing it to figure out which version it is. You know, which is fine. I can do that. It's not the end of the world. But that's basically what, what I think happened. So if I come here and go to GitHub, RIA, RIA tags, come on. 1024 was the last in the 1.0s. Can I see, let's check the date on it just for giggles, which I don't think is going to give us what we want. But 1024 was a year ago, if that's the date you're looking for. I had it have it up on npm. Got it. This says August 4th, RIA.js. All right. So let's look at 1024. I guess it's in dist, right? Yeah, RIA.js. I think I'm also using the min and not the regular. And so who the hell knows if that's the problem? That shouldn't be. Okay. So it's definitely not 1024 because the file we have has a bunch of changes to it, like humongous changes to it, like barely even the same file. If you search the package lock for RIA, does maybe proto buff has a dependency on it too when we have more than one version in play? But we're not, I see what you're saying. Hang on. I'm at the previous commit. So if I look at package lock and what do you want me to search for RIA? Yeah, it's only listed here. Okay. So I don't think it's a dependency of anything. But remember, we started doing, maybe we didn't start doing this more than a year ago. Maybe it's a newer version than 1024 that we have previously because that's, um, no, August 4th is like today. How do I look, uh, can you look through the get history and find when RIA.js was added to the repo the first time? I mean, besides six months ago, which is only slightly helpful. Say what? Besides six months ago, which is only slightly helpful, just with the commit. I don't know what you're, I don't understand what you mean. As far as how long ago it was added. What I'm looking for is I'm trying to figure out if the default encoding changed in RIA. And if so, how do you set that? Like from different versions. So what's happening on the C++ side is it's looking at the message queue with message being specifically a proto buff message. And it's expecting to get a binary message and decode that using proto buff. And instead what it's getting is what it identifies as a map instead of a binary string. It's my assumption based on what I saw when we were stepping through on the client side of things is that RIA should normally, or at least was for us, encoding everything is that, you know, binary December 16th. And with the updated code is now encoding it as some sort of map. So I would, I would assume that's an encoding switch, but 1024 was two years ago. I'm making a lot of logic beeps here. NPM says 1024 was published on August 5th last year, 2020. So just sorry, you said you're looking at NPM. Oh, let me look at the releases history. That's better. That's what I'm looking at. All right. June, April, August 5th. Yeah. And so the when we added RIA was December 16th. 1024 was August 5th, 200 was April 23rd this year. So it's got to be 1024, but I don't understand why the files are so different. Unless I got it from somewhere different. Maybe, maybe you didn't grab the latest at the time. Or mate, I don't even know. I probably grabbed stuff from, I don't, I don't even know. Let me, let me look here. Oh, here we go. Maybe I got it from here. This says November, which could make sense. Get log. Gordon Sim, September 10th, 2020. This is probably where I got it from. Well, so yeah, let me do this. Alice, dist, get diff, dist, RIA.js, temp, RIA. Nope. These are very different also. So I don't know where that RIA came from, but it's like super not the same as anything else. So we just, you know, whatever, like we're done for today, but the problem is clearly the RIA library and figuring out what the difference is. Or figuring out if maybe there's a syntax change or something that we need to fix it or whatever. But I don't, I don't think so because all we want to do is send the body as the binary. So I don't, I don't know what to say. Like, I'm sure if we copy in the file, it's just going to f and work. But anyway. Copy in the file or step back through the versions one by one until you find the one that it is and then use that version number. Well, ideally we should make it work with the, like a new, like a current version of it. Like we should just fix the problem, huh? Yeah, 204 is the latest. Right. Yeah. I mean, for giggles, let's see here. Package. Oh yeah, wait, git branch, git, git, checkout, debug, bypass, SSO. config.js, localhosts8000. Nope. 5672 package.json. Would you say the current version was? 204. And so we need a post install. How do I, oh, so I do npm install? So it's the latest packages? Yeah, you do npm install and it's a regular dependency, right? Not a dev or is it a dev? Correct. Right. And then post install it runs our, what? Sorry, I thought you were going to use npm install to change the version, but you edited the package.json, right? Correct. Okay. Yeah. So I changed it to 204. And so this file, Ria is showing modified. So npm start. It's showing modified. Is it in, is node modules in git? No. We wrote that copy script as a post install, which copies the depths from node modules into, that's this, where is it? Copyrex.sh. I'm assuming copying from the disk is the thing to do. Yeah, that should be it. Here's the server. And then here's the client. Magic. Fing works now. So whatever version we had was like some crazy in betweeny version. It was from the future. It was from the past future or the future past. Like I don't know how whatever got in there got in there, but it's working now. Yay. Yeah. Yay, internet. So let's see. What do I have here? I don't need the manifest snippet. We need package lock. We need package. And we need Ria. Updates Ria version for insane error about. All right. So I pushed it to the debug bypass SSO branch. And with that, I think it's time to go. Yeah. We only spent what the last 40 minutes feeling like terrible programmers. Oh, God. So, so awful. I hate stuff like that. God, it's terrible. All right. Well, thanks everybody. Well, we'll see you next month, I guess. Thank you. Cheers. Bye. Getting kicked in the face for an hour is more like outro.