Build Your Own TwilioQuest Content
with Margaret Staples
TwilioQuest is an educational video game that teaches us to code through 16-bit role-playing nostalgia. Margaret Staples will teach us how to create custom content for TwilioQuest in this episode!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone, and welcome to another episode of Learn With Jason. Today on the show, we have Margaret Staples, AKA Dead Lugosi. How are you doing today? Thanks so much.
MARGARET: I'm doing all right. Thanks for having me on your stream. It's super fancy.
JASON: Super excited to have you here. I think this is going to be a ton of fun. All right. Everyone is subscribing. Thank you so much for the sub. Eco, thank you for the sub. I just got the scoop on this, I didn't realize my last few guests had beards, so I didn't have enough time to get the prop beard over to Margaret before the stream, and I apologize.
MARGARET: We're just gonna have to pretend that I'm wearing Copper Beardy's beard right now. In your imagination, I'm blending in.
JASON: Thank you for the cheer, razor 1. Okay. So, Margaret, for those of us who aren't familiar with your work, do you want to give us a little bit of a background.
MARGARET: Sure. My work, that's funny.
JASON: All right. Here we go. Hype training.
MARGARET: I'm on a team at a company called TwilioQuest, and Twilio is actually, like, a pretty big tech company. Not when I was hired, but it's been growing really fast since I was hired. Now it's a pretty decent sized tech company. I work on a teenytiny team on that tech company and all my teenytiny team is we work on an educational video came called TwilioQuest, which is what we're going to be looking at today. TwilioQuest is a free educational video game that mostly teaches programming skills. And we recently, this year, released a new feature which is an authoring guide. So, that if you want to create your own educational content within, like, a 16 bit game that you can do that and add to our community of learners' experience. We're currently developing, like, an extensions gallery platform so that we can review communitycreated content and make it available more easily, and it's very exciting, and I would love more people to make custom TwilioQuest content.
JASON: And that's exactly what we're gonna do today, which I'm really excited about because I don't I'm not a game creator, right? I've done a couple streams throughout the history of Learn With Jason where we've played with certain game mechanics, like we opened up some 3D modeling and we got ourselves, like, a little walking dog model in one setup, and then we've so, we've done little bits. Oh, what's up, Ben? Hello, everyone, on the raid. Welcome, welcome, welcome. And so, you know, for me, game dev is one of those things that I've always wanted to learn how to do and to make things more interactive and playful. And so far, I've kind of been limited to things I can do with buttons like Tic Tac toe, right? So, I'm excited to learn a little bit more about this. I think the 16 bit games, they really have a special place in my heart. I came up in that generation of that was the option. It was that or nothing, so it's very exciting for me to kind of see how this all works.
MARGARET: Yeah, we're gonna make a game developer out of you right now. It's happening.
JASON: Yes, I'm ready. Okay. So, let's talk about this a little bit because I feel like there's just that immediate mental hurdle that I face, which is it's too much. Like there's graphics, there's motion, there's collisions, there's points, there's all this stuff that starts happening when you start thinking about how to make a game, and my brain immediately goes, no, that's too hard. I should stop.
MARGARET: So, in the developer community, one of the things that I, like, first of all, like, my early professional life was absolutely impoverished by the fact that I did not know the developer community was a thing. Like the first decade that I was working professionally as a developer, I did not know that there was a community out there to, like, help me on that journey. Once I found it, I realized that's, like, unlocking special bonus powers, having a community you can interact with about this stuff makes you pick it up so much faster.
MARGARET: What I learned after joining said developer community was that if you really want to become an expert at something, you don't just learn it, you teach it. And so we wanted to make creating this educational content accessible to developers, not professional educators, not professional game designers. So, we wanted to take as much of that scary "too much" out of to, which is why we created an extension template. Just like with any other development, first thing you do is you clone the repo. So, you clone the repo, and what you find in that repo is a bunch of defaults to start with, including an already premade map. Not only is it a premade map, it's a premade map within a bit of lore trickery that allows you to keep it as simple as you want to keep it. So, in the lore, these custom extensions, by default, are offered in a VR training environment. And by VR, I mean '90sstyle. Everything is neon and partially void. So, if you want to keep it really simple, if you don't want to do I've actually seen people create really amazing educational content just by cloning that map over and over again to make more missions without having to approach the map. I've also seen people who got really into the map creation, but who weren't really into more of the, like, technical checking people's work bits who made, like, fun just explore it levels just by modifying the map without digging into the programming piece.
JASON: Oh, okay.
MARGARET: Whichever piece you feel inspired to dig into, you can just focus on that and let the extension template do the heavy lifting in all the other areas, is the idea.
JASON: Nice, nice. Yeah, so I think this is exactly what I need, is training wheels for my brain so that I can get into this without feeling overwhelmed by it. And, you know, I love that you took the time to do this. I feel like that's such a big thing.
MARGARET: Oh, shoutout to my team, because I personally did not. (Laughter) We have a teenytiny team, and each one of us is wearing, like, at least three hats. None of the hats I'm wearing have done any of the heavy lifting when it comes to this authoring guide. Shoutout to Ryan and Kevin who did all the heavy lifting for the authoring guide. My big contribution has been making sure our community is aware of it and making sure that the learning resources that they need to engage with it is there. Like I'm much more of our community human. I have developed content in TwilioQuest, but not nearly as much as I would like, because time is finite.
JASON: Really is the big bummer about time, is I'm, like, I look at my todo list and I see the time passing and I go, so, that's just not gonna happen, is it?
MARGARET: Yeah, yeah. Honestly, one of the skills that I've really had to master as I've gotten older is saying no to things that I would really like to say yes to, because there is
MARGARET: Only a finite amount of time and energy and focus. And making choices is important.
JASON: Yeah. And you know what? That's maturity as an adult. Like I feel like when I really started to feel like a grownup is when I could walk into a restaurant and say, you know what? I'm actually not gonna eat that onepound block of cheese that you're willing to serve me, because I know that ultimately that's not gonna make me happy.
MARGARET: Oh, yeah, absolutely. Okay. So, like, one of the one of the weirdly adult things that I now do is I ask about the desserts first so that when I'm making my meal selection, it is, like, well, if the desserts are crap, then I'm getting the steak. And the steak and both the meal and the desserts. If the desserts look amazing, maybe I'll get a salad so my dessert is gigantic. This is adulting.
JASON: Yeah, Cassidy is saying knowing what I ate last week. We were in Chicago for a team offsite last week, and we ate everything. There's nothing Chicago is a wasteland now. It's just all the restaurants are like, sorry, no food.
MARGARET: You went, like, full Godzilla and were scooping humans off the street and munching on them. There is nothing in Chicago right now.
JASON: Just tumbleweeds and regret. (Laughter)
MARGARET: Honestly, that sounds like it would give you indigestion.
JASON: You know, you're not wrong. So, let's talk let's see is it worth talking or should we actually start doing something? I feel like it might be time to
MARGARET: I probably should have asked this before I got on. How long is your stream?
JASON: We've got 90 minutes total.
MARGARET: Oh, okay. So, that is more than enough time to look at things. So,, like, we can make words. We can make code. Whatever you like. Mmhmm.
JASON: All right. Why don't we do this, let's switch over into the pair programming view, and we'll start looking at what the what the components are, and then I'm sure I'm gonna have more questions because I know that
Oh, so, we would need to add code. Is that right?
JASON: That's correct. We're gonna add some code. So, let's do this. Here we go. Let's get over there. Pair programming. Here we go. All right. So, we're looking here, and before we get started, let's do a quick shoutout to our captioning. We have Jordan here today from White Coat Captioning writing down all the things that we say. So, Jordan, thank you for doing that. That is made possible through the support of our sponsors. Netlify, Fauna, Hasura, and Auth0 are all kicking in to make this show more accessible to more people, which means a lot to me. So, thank you all very much for kicking in.
MARGARET: Did you know that one of the most amazing things about White Coat Captioning is that they specialize in captioning things that have really technical vocabulary. They actually will, like, study tech vocabulary or, like, medical vocabulary depending on, like, what they're doing the live captioning for so that they can do it so very fast. That's why they're so good at what they do, they realize that different context require different topofmind vocabulary. They do that nerd work, and I love them for it.
MARGARET: If you want a TShirt, you should become an active part of our community. We love I love swag drops. So, like, if you are an active member of our community, specifically if you join the Champions Program, which is Twilio's version of awesome community leaders, then you get regular swag drops.
JASON: Oh, dang.
MARGARET: I'm always looking for excuses to drop swag on people. For example, the scholarship program. Twilio does an annual conference. This year, it's happening in October and I run our scholarship program for underrepresented developers. As part of that, this week, I am packing up, like, love boxes of swag and goodies for our community humans that are going to be part of that program. That's very exciting. So, join the active community and swag drops will happen.
JASON: Is it Twilio Con? Am I searching for the wrong thing? It's called SIGNAL now.
MARGARET: It hasn't been Twilio Con in many years. It's so cool that you know that.
JASON: My experience with Twilio is really funny because I went to Twilio Con and I didn't really know anything about Twilio at the time. I knew it was up and coming. I ended up hanging out with Jeff Lawson, but I didn't know who he was. I'm there talking to him like he's a rando at the conference and then he got up on stage. Oops. Okay.
MARGARET: Jeff is our founder/CEO, and he is a big nerd energy and I adore him. He is absolutely, like, a developer to his core, and he is the reason that we are both a developerfocused company and it's the reason that, like, one of my favorite internal sayings that is very core to our culture is keep Twilio weird, and I am about it. I am doing that mission.
JASON: I love it. I love it. Okay. So, let's I mean, yeah, let's speaking of weird, let's get weird. I want to make some I want to make something. So, what is my first step if I want to get this thing up and running? Because what I'm looking at here, this would be to play TwilioQuest, right? To download it.
MARGARET: Right. So, you're definitely gonna need to download it so you can install your extensions into the game.
MARGARET: So, definitely, step one is downloading it for Mac or windows or Linux depending on your operating system. After that, you want to head over to the extension docs, which I have just posted in the chat, a link for that. That is where all of our existing documentation for creating your custom extensions is. This is a work in progress. As I mentioned, we are a teenyteenytiny team. Sometimes there is a lag of it getting implemented and getting into the docs. Which is why we have a special thread in our forums for requesting us to demo certain things during our developer streams which happen every other week during TwilioQuest Tuesdays on Twitch. Twitch is where I was just doing this with Ryan. Hey, Ryan.
JASON: That's under the TwilioQuest account, right?
MARGARET: Yes. Twitch.TV/TwilioQuest. We stream every Tuesday at 9:00 a.m.. Every other week is a developer stream, and every four weeks is an event stream where we do four hours of streaming where we are raising money and awareness for a good cause, and our event stream for September will be next week, if you wanted to tune in.
JASON: Nice. Nice. I just realized my thingy locked up, so I'm just gonna reload that real quick. There it is. Don't know why that locked up. All right. Yeah. So, go check out TwilioQuest. Get a sub in there. What's the saying, ring that Bell, smash that subscribe button, ring that Bell.
MARGARET: Yes, do all of the things. All of the internety things.
JASON: Okay. So, I have here's my TwilioQuest, let's see, it doesn't quite fit on my browser, but it should be okay, right? Can I shrink this a little bit? I can. Okay. There it is.
MARGARET: Okay. So, do you see next to the current version where it says "more?"
MARGARET: Click the "more," now use the drop down. Now go to the preview. Because all of the new extensions are on the newer version with all of our custom art from our amazing artist Kerry. If you go to the preview version, then that's actually gonna be what you're gonna be creating your custom extensions for, and that is the preview until SIGNAL when we launch it and it becomes the official version.
MARGARET: So, you are very cutting edge right now.
JASON: That's all I've ever wanted. Okay. So, I am I am now on the TwilioQuest 3.2 preview. Looks like we're using Alpha 21. Should I play it?
MARGARET: If you just want to pop in and see the see the opening cinematic stuff, you are absolutely welcome to preview that amazing content.
JASON: Ooh, hold on. Hold on. I got to reroute my sound. Let's go to the this one. Okay. (Arcadestyle music playing)
Much of our lives take place in the virtual worlds of computers.
JASON: I love it.
This vast virtual universe is known as The Cloud. The power of code.
MARGARET: In the chat done most of this work.
Software developers wield the power of code to create new worlds, where anything is possible. There are those who seek to contain the power of code, to protect their hoarded wealth and privilege. We call these forces the Legacy Systems. The TwilioQuest Program was created in secret to confront this threat. They would recruit and train an elite corps of software engineers known as Operators, to explore and safeguard the wild frontier of The Cloud. Operators have little in common with one another, except a solemn oath: To use the power of code only to unlock hope, power, and freedom
JASON: This is so good.
for all of humanity. You are an Operator, and you have been asked to undertake a critical mission. You will assume command of a prototype Cloud Exploration Vessel designated the Fog Owl. If you can demonstrate the effectiveness of this new technology, it could help turn the tide against the struggle of the legacy systems. It's time to begin. Your neural interface should already be programmed with the location of our secret research facility. TwilioQuest scientists will provide further information upon your arrival. Good luck, Operator. We'll see you in The Cloud.
JASON: I love it this is so good. This is so much fun, right? Like I love the whole oh, and then you get to customize?
JASON: Oh, this is good. Oh. Oh, boy. Wait, can I be no hair?
MARGARET: Yep. Oh, wait, hairstyle.
MARGARET: But that's gonna be a style.
JASON: Yes. It's so good! Oh, my God, I love this so much. This is amazing. Okay. That'll be me. This is great.
MARGARET: Okay. So, spoiler alert, or I guess cookie is Chiara is a team member of ours. Kerry, our artist, all the MPCs in the game are modeled after people. So, Chiara is actually, like, one of my team humans and that's not not what she looks like. So, that's fun.
JASON: I love it. Okay. All right. I'm just gonna wander around here for a minute because it's just fun to me.
MARGARET: That's fair.
JASON: Okay. I can do something. (Arcadestyle music playing)
MARGARET: So, most of this intro stuff is just going to be that's me.
JASON: Oh, hey. We know that person. This is super fun. I love this. Okay. So
MARGARET: Kerry actually, like, let us give feedback. So the weird, like, lines on my face are because I am absolutely an Android in this game and that is delightful to me.
JASON: I love it. Okay. So, let me maybe get into the settings here. I'm going to take the master volume down a bit. (Arcadestyle music playing) And then let's take everything down so it's not quite so overpowering as we're talking. But this is this is just, I mean, it's a game. It's a whole game. This feels
JASON: just like something you would get, you know, it's not, like, a you know sometimes you see, like, a thing that gets launched and it's, like, oh, we built a game. Okay, you got half a level and, like, it feels really kind of junky, right? This feels nothing about this feels halfassed.
MARGARET: Well, this is many iterations down the road. So, when TwilioQuest was first created, it was created by our Developer Education Team to service the curriculum for our Training Days which are called Super Class because we think we're funny, and we're right. So, at first, it was just a bunch of 8 bit style gammaifications. It was very much choose your own adventure and you can rack up experience points and, like, get loot items that would show up on your Avatar. That was it. It was a web page with microtutorials. I immediately loved it. I didn't need it to be more than that for me to completely fall in love with it and take it to conferences and give people arcade prizes. Because I'm an '80s kid. That's what we do. Then it got sufficiently popular that its creator, our fearless leader Kevin, got to turn it into a legit video game. Like the magic of it is that it's an Electron app. We're teaching web development skills within a web development framework. When you're creating your own content, you have beings you need to work out, pull up your developer console and it's like you're troubleshooting for your web development game, only it's a game. Which is meta, in a way that I love.
JASON: I think I probably would be able to sit here and play this game for the rest of the stream, but I think that's for another time. So, why don't we start actually building something here. So, what is my what is my next step?
MARGARET: Next, you're going to want to go to the extension docs.
JASON: Okay. So, I'm just going to minimize the game here. I like that we can still hear it in the background. We'll just keep that rolling. (Arcadestyle music playing)
Okay. Extension docs were here. I'm looking right at them.
JASON: Okay. So, I'm ready to begin my adventure.
JASON: All right. I'm going to skip the walkthrough. I will let you be my walkthrough today.
MARGARET: That's fair. So, this is your actual step one, because this is the documentation, but also you're not documentationrelated step one is going to be cloning the extension template repository.
JASON: Okay. The repository is down here, I assume?
MARGARET: I mean, Brian, correct us if we're wrong, but there should be a link in here, right?
JASON: Let's see. Template repository. There it is. All right. So, I'm going to take this and we will create a new repo here. How do I want to do this? Gh repo clone?
JASON: Clone. And we'll call this a twilioquestextension.
MARGARET: And Ryan mentions that you do need to create a directory to hold your extensions.
JASON: Okay. So, like, what I've done here is not I need to make a folder above the repo?
JASON: Okay. So, let me make a directory.
MARGARET: The point being that, like, if you were going to install this, this wouldn't be the whole game, this would be one amongst many extensions.
JASON: Oh, I got you. Okay. So, I'll create a directory called "extensions," and then I'll just run that same command, but we'll put it into extensions. And then I can just remove everything in here, right? What else do I need to get rid of? Let's get read of the README. The levels, package, extensions, objects, scripts, images, and the tilesets. Okay. Oh, no, I did it I typed extensions when I definitely didn't mean to. Okay. We're gonna do that one more time. Here we go. Damn it. I thought I was doing so well. All right. So, here's extensions. Let's move into it. I'm gonna actually open this up. And so here is here is the extensions folder. Inside of it, we have everything that I just cloned out of that repo. Okay. Let's look at the README. And it's got all of these goodies in it, so we can go back to the docs that we were just reading. Got the template. And npm install. Okay. I can do that. Okay. Now, I just realized, do I need to, like, name my extension and have that in its own folder, too?
MARGARET: It's funny, because what you've done is you've given a singular name to the multidirectory and you've given a multi name to the singular directory, and that took me several readthrough to understand what had happened.
JASON: I think I may have just confused myself. (Laughter)
MARGARET: So, you want an extensions directory, and then within that, you want to clone the extension template with its own custom name for the new extension you're gonna create.
JASON: Oh, okay. I think I can just do this and it'll just work. Let's see. No. But if I create
MARGARET: And Ryan is attempting to drop you deep links for the docs. Because he's a super helpful human.
JASON: I appreciate it, Ryan. So, if I just start moving everything in, is that gonna you just gonna work?
MARGARET: I mean, probably, but, you know, technology's kind of
JASON: I believe. All right. We're in. So, I have an extensions directory. I've now named a folder. Okay. Do we need to take a break? I need to lie down.
Woofta. All right. That's exciting.
MARGARET: I promise this is not nearly as difficult when you're not also attempting to stream at the same time.
JASON: Yeah, just me over here trying to keep up with lots of new things. Okay. But, now that I have this I believe in the right place. Path to extensions folder, good. We're into the repo name. We've installed. And now I can go into extensions under after cloning extensions into the extensions folder, you should be able to see it in the extensions submenu, under Settings in the game client. So, I need to go and find this, right?
JASON: Okay. Let me pull this back up. And here, extensions. And I'm going to find my directory. Which is under here. Here. Here. What did I call this?
JASON: Did I just call it "extensions?"
MARGARET: I don't know, that happened once. One directory you called extensions.
JASON: TwilioQuest extension.
MARGARET: Oh, that's right. The singular directory is the
JASON: Okay. And then extensions, right?
JASON: Okay. I did not make this easy on myself. All right. So, we have these are our extensions. We have these two loaded extensions.
JASON: Extensions are being loaded from the directory above. It says "none."
MARGARET: Ryan thinks we'll need to exit the game client and load back in in order to see the default mission.
JASON: Okay. Cool. I can do that. So, let's quit the game. And we'll open it again. Let's make sure
MARGARET: You'll want to select the right version again, which in the future will auto select. It just doesn't right now.
JASON: Okay. And now we have it. I have one it looks like I have a
MARGARET: Oh, it looks like your�.git directory stayed. It thinks you're trying to load two directories, one of which is named�.git.
JASON: Okay. I did this all sorts of wrong, but we're just gonna be okay.
MARGARET: You're doing fine. It's fine.
JASON: But we're in the right place now. We've got I put this into my downloads folder. That's why it's weird. Okay. I will fix that later. But we have this extension here.
MARGARET: Yep. It is now it is now loaded. So, if you want to go back into your game,
MARGARET: and you can go look around for the VR terminal, which will probably be down and to the right. I could be wrong, though. Oh, I'm wrong.
JASON: VR terminal?
MARGARET: Or we can do the console warp. (Footsteps)
JASON: Console warp. How would one do that?
MARGARET: Okay. So, if you open up your developer tools, which is probably you probably need to yeah, mmhmm.
JASON: What am I doing? Toggle developer tools. There it is.
MARGARET: Developer tools. Yeah.
MARGARET: Then go to console. And then typeytypey.
JASON: What do I type?
MARGARET: Work open parenthesis and then single quote and fog_owl and closed quote and closed parenthesis. Or copy and paste from where Ryan posted in the chat.
JASON: Okay. Hey, look at me.
MARGARET: Now you're in the what will once you finish the prolog be your default starting place, which is the bridge of the Fog Owl, which is your spaceship in The Cloud. Down to the right. This is the VR console.
MARGARET: And there is your VR Mission Template. So, this is what you can modify to create your own custom content.
JASON: Oh, okay. So, when we go into this, am I, like, a little bit I think I squished it all a little bit when I moved the things around. (Footsteps)
MARGARET: As you can see, we are very 1990s lawnmower man/Tron situation kind of VR.
JASON: This is so fun. I also love that everybody's in here. Oh, Ryan, look, you got a photo. (Footsteps)
MARGARET: So, lots of this stuff is in there specifically to demonstrate stuff that you're gonna want to make use of when you're creating your own level design. So, this is that little globe is an interactable object. The treasure chest is one of the ways that we have to give objectives. That's generally for objectives that don't have prerequisites. Whereas the laser barrier is an option for creating missions that objectives that have prerequisites because, like, a laser barrier, you can't pass it. So, the later ones can depend on the former ones, if that makes sense.
JASON: Yeah gotcha. Yeah, yeah, that makes sense. That makes sense to me at a high level. So, when we climb in here and look what's going on. We can see, let's see, we've got some images. There's Ryan.
MARGARET: Showing off how to create a custom avatar for your NPCs. Mmhmm.
JASON: Got it. Got it. We've got templates, conversations, objects, there's a little icon.
MARGARET: The globe, you can use the globe's custom interaction stuff to mimic to create your own. It's an example piece.
JASON: Got it. Okay. Then we've got a green light. So, as we're kind of poking around at all these, like, I'm guessing this is the green light.
MARGARET: Yep. Those have those are also conditional. So, those will turn on when you complete the treasure chest mission, if I'm remembering correctly. I know they're conditional. I think they're conditional on the treasure chest mission.
JASON: Oh, nice. Okay.
MARGARET: So, if you click back to "tutorial," it will give you the option to complete it again.
JASON: What is the name of the company that makes tada.
MARGARET: That's what our learning objectives look like. This is obviously just an example, but every learning objective has this basic interface. It's called your hacker interface. And it has each one has three tabs. The first tab just basically tells you the name of the objective and what you will get if you get it right. The second is, like, a checklist of what you need to do, and then the third tab is the deep dive help tab, where if you're not really sure how to do what they're asking to you to do, you'll find lots of information in step by step and links to external resources to help you out.
JASON: Nice. No, this is great. Okay. So, if I want to make one of these, then, it sounds like I go into the objectives? Which are where? I had this. Objectives. So, there's an example objective. And you get just some HTML. That makes sense to me. You have code samples. Okay. So, this is just like writing a blog post. That's great. And then you have a JSON object.
MARGARET: So, this is where you kind of define the structure of your objective. This is where you will give the information that will appear on that first panel, just the vague the title, the innovation description of what it is, and you that's where you set how many answers you need and of what type. You can also have them you can also have objectives that don't require them to put in anything, and they just hit the "hack" button and then the objective can check that they've done things on their computer. That's how we check things that are, like, programmingtype objectives.
MARGARET: You can just say here's what you need to do, when you're done, hit the hack button. When they hit the hack button, the validator will validate whatever you told it to check. Maybe that's installing something. Maybe that's writing a program that does something. If it passes all the checks, you pass. If it doesn't, we try to do this really well and we encourage other authors to do this really well. We try to give super informative error messages. Because what we have found is that developer humans don't much like reading the docs. So, a lot of them will just jump in and try to, like, complete the thing based on, like, a glance at the objective, and then the first real feedback you get to give them is whatever error messages you put in.
JASON: Good. Good, good. No, this is great. I love this. So, helper validation fields. So, this is cool. Like, I like this. This is so, we've got our helper. And so, where where do the actual answers get set?
MARGARET: Okay. So, that's gonna be in your in your validator. Yeah. In the discrimination is where you tell it whether or not it's accepting answers.
MARGARET: And what they get if they get it right, and the title and description. And then in the validator, that's what will run when they hit the "hack" button.
JASON: So, here's my helper. And where did the helper come from?
JASON: But it looks like the answer 1, and then this is Twilio comes from where?
MARGARET: So, the validator fields are specified in the description, and then the helper delivers them to the validator.
JASON: Oh, I understand. Okay. Okay. Got it. All right. I understand what's happening. And then we've got another one here where we've got a description.
MARGARET: And on the map on the map, unless I am mistaken, that first example will be the treasure chest, and the second example will be the laser barrier. And as you can see, because you completed the treasure chest, now those lights are flashyflashy.
JASON: Mmhmm. Yeah, so, same deal here.
MARGARET: And now you can see that when you complete this one, the laser barrier goes away.
JASON: And this will let me exit, right?
JASON: Oh, and now I'm on a
MARGARET: Now you've transitioned maps.
MARGARET: Right? It's fun.
JASON: This is great. (Footsteps)
JASON: Cool. Okay.
MARGARET: So, there's also, like, conversations as part of the extension template, and that is probably obviously how the interacting with the NPCs gets specified. So, if you are super into creating the learning objectives, you can dig into that and leave everything else as default. If you're super into map creation, you can tackle that and leave everything else as default. If you're super into, like, storytelling, you can really tackle that. It leaves you to tackle whatever piece you're feeling inspired by without having to stress about all the other things.
JASON: Mmhmm. Okay. Cool. And then we've got it looks like maps. So, maybe what we should do is we should we should mess with some of these a little bit. So, let's change the rules for one of these objectives. I want my objective to be what is what is the right way to greet a Corgi? Okay. And then down here, what I want in my validator is for this, we can go simply string to LowerCase. And we can say I'm immediately violating the first rule in providing unhelpful hints, but let's give this a shot. Do these hot reload. If I come back in here, is it already running? It is! So, yeah, if you like, you could you could argue that you should pet a Corgi, but you would be wrong. Oh, but it gave me the wrong answer.
MARGARET: That's because it checks in order. And you got the first question wrong.
JASON: That's right. That's right. That's right. Okay.
MARGARET: Fail early, fail often. Uhoh.
JASON: Am I in the right one? Example objective, yes. Maybe it just didn't quite reload yet?
MARGARET: So, if you leave the mission and then come back to the mission, it should reload it, is what Ryan is saying in the chat. See, that's why I couldn't answer you when you were like will this have already changed? Because there are, like, different versions of yes and no to that question. Because some things require, like, some things don't require anything. Some things that you can, like, trigger the reload in, like, the console. Some things you can just exit and come back in. Some things, you have to leave the whole game and come back into. And I don't know which is one of those, which is why I read Ryan's messages in the chat.
JASON: Okay. So, we'll go with Twilio, and then we will
MARGARET: And chat says maybe you changed the wrong validator.
MARGARET: Maybe you changed
JASON: You are not wrong. Yeah, I'm not sure why it's giving me a different answer here.
MARGARET: Did we leave did we leave did we go back to the Fog Owl and come back?
JASON: I did.
MARGARET: We might need to exit the game and come back. I don't know.
JASON: Let's try it. Okay. Bye. Then we'll do it one more time.
MARGARET: Oh, and did you save?
JASON: Always a good question. I did. So, let's get into the preview. I guess what I can check next is if I get in here, I need to warp again.
MARGARET: Yeah, because you haven't completed the preview stuff where you run around and talk to people and it explains to you how to play the game. (Footsteps)
JASON: Okay. Here we go. Now if I come in here we'll say that. There we go. There we go.
MARGARET: Yay. We got the right wrong answer!
JASON: Now, if you boop it, you succeed.
JASON: Okay. So, we have done some actual gameplay here. We changed an objective. And so you're saying that the other way that this can work is if we if we want to check, like, external code, we can do that as well?
MARGARET: Which is how we do things like so, the level in the old version of TwilioQuest that I personally developed and is my baby, because I got to make a game level! Is all about PHP. So, I use this to do things like check whether or not they have the right version of PHP installed. Check whether or not they have the Package Manager installed. Check whether or not they have followed instructions to install specific components. Like it just you can just check directly and then give them that direct guidance, which, honestly, is one of the most valuable parts of TwilioQuest, because as a developer, especially when you're just getting started with new technology, there is there is such a gulf between reading it and then implementing it and then knowing what piece of it you didn't get quite right or whether what you read is now out of date, and, like, that can be so incredibly frustrating. So, it's very nice to have that feedback loop of it told me to do a thing. I did the thing. It told me I got it right or it told me I got it wrong.
MARGARET: So, we ask okay, so, I may or may not understand your question. So, the way we do it is we get the player to tell us where we should look for their code.
MARGARET: And then and then we tell the player what to name it, and then we run it.
JASON: Nice. Okay. So, if if we wanted to do that, well, actually, let me ask, given that we've got about 40 minutes left here, and I know that we wanted to look at editing the map a little bit as well, how deep down this rabbit hole should we go? What should we look at first to make sure we cover everything?
MARGARET: Because you're interested in code and IDE things, I want to point out Ryan has highlighted the fact we actually do have an ingame IDE. If you wanted to add the ingame ID E to your hacker interface, that's in that JSON. So, it's not required. It can be useful, but also, like, you can people can just use whatever IDE they want. But it can be useful because then you can put, like, the surrounding code bits that you don't want them to have to worry about and you can just have them, like, tweak code instead of having to write from scratch. So, it's very useful in that way. To have the builtin IDE. But, yeah, I definitely think that before we completely run out of time, we should open up Tiled and look at how the maps are put together, because that's super fun for me. It's all super fun for me. Literally whatever you want to do. I love my job.
YAML, YAML, YAML, JSON.
JASON: I just hit the show IDE, right? Did I typo it? I'll fix it. I'll fix it. Okay. So, if I go back, open it again.
MARGARET: You'll probably need to leave the no, show code editor. It's right there.
JASON: Ryan put in a hack to do so that it wouldn't require that again. Wait, I hit the
MARGARET: But it didn't do the thing.
JASON: It didn't do the thing.
MARGARET: It didn't do the thing, Ryan.
JASON: So, maybe I do need to leave and come back.
MARGARET: Ryan hasn't deployed that fix yet.
JASON: Ah, perfect.
MARGARET: It's fixed in main! Consequences of a teenytiny team. (Footsteps)
JASON: Okay. So, I am gonna have to quit the game and come back in. Let's do it.
MARGARET: Ryan's pointing out that we are on the alpha preview version.
JASON: Yeah, definitely taking all of this with a grain of salt, because we are living on the edge, y'all.
MARGARET: We are the cuttingest of edges. Mmhmm.
JASON: Let's see. So, let's go into
MARGARET: And Ryan says the code editor is broken. So, we might still not see it.
Holy buckets, did that just work?
JASON: The code editor is broken. That's fine. So, we'll head out to the Owl. And then let's hop back in here. (Footsteps)
(Beep) And now I think we should all be running the well, I guess I should rerun that reload external modules. Okay. So, that should pull everything back in for us. So, why don't we move on then? Let's what's the next thing we want to look at?
MARGARET: Okay. So, either you can look at it depends. Would you like to look at content to see how things are implemented or would you like to open up the map editor and look at how things are laid out?
JASON: I feel like the map is probably the biggest mystery to me. Chat, do you have preferences? Contents or maps? I'm gonna start looking at maps, but if y'all overwhelmingly say you want to look at content, we'll switch.
MARGARET: Oh, yeah, special requests always welcome.
JASON: Mmhmm. Okay. So, if I want to do maps, I can see over here in the docs there's a thing about editing maps. It's a work in progress, so I'm gonna lean on you.
MARGARET: That's totally fine. So, the first thing, as I mentioned before the stream, but our chat did not see that, the first thing that you need to do if you want to edit maps is download the Tiled Map Editor, which is how we edit our maps.
JASON: Yes. So, here is the Tiled Map Editor. And this is it's free. It's donation ware, so if you're going to be using this a lot, maybe kick them a couple bucks. All right. So, I
MARGARET: Also open source all of the things. Mmhmm.
JASON: Okay. So, I have Tiled. I have opened it. And this is the extent of my understanding.
MARGARET: Cool. So, now you're gonna want to open and navigate to that extension directory so that we can find our default map files.
JASON: Okay. Oh, wait. I put this one in my downloads, didn't I? Let's go in here, and here, and here. I guess I can just this one extensions. Or does it want this one?
MARGARET: Keep going. Keep going.
JASON: Into the levels?
JASON: Maps? Wait.
MARGARET: Yeah, mission template and then maps.
JASON: Okay. Still doesn't want to let me open.
MARGARET: Did we
JASON: I thought I opened project, but it doesn't seem to do I need to open file?
MARGARET: Avenash thinks that we should open file.
JASON: Okay. Let's open file. We'll do that same thing. So, downloads, here.
MARGARET: And Ryan agrees. So, yes, open file instead of open project.
JASON: Maps. Space garden. I like that. Space garden. Let's do that one. Okay. Okay. So, this looks fun.
MARGARET: So, here we are in Tiled. So, just some basic orientation around the Tiled UI. In the upperleft is where you're going to see all the information on whatever you have selected, generally objects, and that's super important because to make things interactable in the game or have custom behavior in the game, you need to be able to set that object's information or grab its ID and grab its ID. That's where you're gonna find it, in the upperleft area of the UI. The central panel is pretty obvious. That's like your canvas. In the lowerright, that is your objects palate, and also, like, your environment palate. That's your palate. And then above that is where you're gonna find your layer selection. And that does matter. As you can see, things stack on top of each other, and some layers have special functionality like the collision layer. It won't show up on the map, but you can see all of the pink stuff outlined on your map.
MARGARET: Those are all drawn on the collision layer, which is kind of exactly like it sounds. Anything you draw on the collision layer, your avatar will not be able to walk through. It's a collider.
JASON: Got it. Okay. Then we put a little exit tile here. So, you mark collision for the trees. If I was like don't walk on the flowers
MARGARET: You could put a collision barrier there, too. If you'll notice, not the whole trees are collidable, and that's to give more of the impressions around layering. Because you can walk behind a tree, even though you can't walk through a tree.
JASON: That's cool.
MARGARET: And Ryan mentions that you can also click the eyeball in the the UI next to each layer if you want to be able to hide stuff. Like if you don't want to have to look at the collision layer, you can turn it off. Which, you know, is good, because you only really want to view the collision layer when you're working on the collision layer.
JASON: Oh, and then here's my custom stuff. And then there's, like, TwilioQuest stuff and a whole bunch of tiles and fun things.
JASON: This is cool. Okay. So, if I want to put, like oh, wait, how do I do I have to, like, grab the whole thing like this?
MARGARET: Or you can do it one square at a time. It's entirely your call.
JASON: Oh, God, how do I actually move things? Okay. So, if I if I select this whole thing, do I view tileset, export?
MARGARET: I think you just drag it on to your map.
JASON: Oh, so, after I've selected it, I can just move it over here and say, let's put some trees over here.
JASON: All right. Oh, wait, I put that on my collision layer. Incorrect. Let's put it on objects, probably?
MARGARET: You can toggle the eyeballs to see where the existing trees are.
JASON: Top. I'm gonna put it in top. Okay. So, I've put it in top. Now I want to go to collision. And I want to actually
MARGARET: Grab that collider, mmhmm.
MARGARET: And my understanding is that it doesn't actually matter what tile you use. Keeping them all the same is useful for your eyeballs.
JASON: Yeah. Okay. So, then if I hide this top. Oh, but then it loses the how did this happen? They just grabbed one, one thingy. Okay. So, let's go over here and grab my one thingy. And then I'll put it on the decoration? Yes. Okay. So, decoration. Boom, boom. Oh, wait. Actual thing. Okay. I'm doing it. It's happening.
MARGARET: You're doing it. You are a digital guru.
JASON: You're doing it, Peter! Okay. So, all right. I added some trees. So, if I save this
MARGARET: Save it, yep.
JASON: Is it did I do it? Is it working? Like if I go in right now, is that gonna hot reload? (Footsteps)
MARGARET: I don't know which of the various reloads will be required. Oh, hey, look, your trees.
JASON: My trees! Okay, so, I'm seeing a couple mistakes I made. Like I put the shadows on the top layer, so I look like I'm underground here.
MARGARET: The depth is really gorgeous, and I love that Kerry has given that to us, but it does make it a little bit finicky. It's a gorgeous effect. When you're walking above and behind stuff, it's a little tricky.
JASON: This is great. How cool is this? So, if I go to my top and I delete okay. So, you go away. How do I even do that? Because it's two layers. Hmm.
MARGARET: Oh, something to know is that unless I am very much mistaken, your avatar will be walking around on the objects layer.
JASON: Objects layer? So, if I take these out
MARGARET: So, anything that you put on the top layer will go over your player, and anything you put on the lower decoration layers will go under your player.
MARGARET: There are multiple decoration layers because sometimes you want that for effect rather than depth. Mmhmm.
JASON: I think I know what I'm I think I know what I need to do. So, here's my theory. So, I'm gonna delete these two. I'm gonna go to "decoration," I'm gonna take this, and then I'm gonna take this one. Right? And then I'm gonna go to the top and I'm going to take this and put it right there. And then I think what'll happen now that I've done that
JASON: Okay. And I need to leave.
MARGARET: Oh, and Ryan mentioned that you can actually warp to the level that you're already in. And that is a that is one of the many forms of reload.
JASON: Oh, that's cool. Okay. So, if I did this right, what'll happen tada. I'm the greatest game dev alive.
MARGARET: Good job.
JASON: All right. That's starting to make sense to me. I am understanding how this works, right? So, the cool thing about 2D art is that you're only thinking about one plane. If the things that you're making have a transparent version, and, like, the thing that's cool about this is each of these trees is really identical, but by combining them in different ways, we get oh, I need to make that different. But by combining them in different ways, we get what looks like a varied landscape. So, we can kind of see, you know, the flowers themselves are all the same flower. These little trees are all the same little tree, but because of the kind of different arrangement, they start to feel very unique and it starts to, you know, feel like an actual world. (Footsteps) So, we can just get clever with our shadows and that tree overlay. Bada Bing, Bada Boom. Very cool. This is very cool. Great job to you and the whole team. This is excellent. I'm a game dev now.
MARGARET: Yes. That has happened. That has happened. I have watched you become a game developer. Mmhmm.
JASON: It's a good day. It's a good day. I'm feeling good, everyone.
MARGARET: Now, now, this does mean that I feel that you've committed to completing an entire TwilioQuest extension so that we can feature that TwilioQuest extension on the new Extensions platform that we're working on. Mmhmm. Mmhmm.
JASON: Might need to do it. Okay. So, for that to be true, it feels like there is one more thing that I need to understand, which is Netlify and TwilioQuest, I think it it could be a thing. This is a lot of fun. Let's maybe let's maybe poke it. How could I I want to I want to set the folder that somebody's supposed to check. So, if I want to do that, let's make that happen. So, let's say I've got my, like, my extensions here in this Learn With Jason extension. What if I just for the sake of this, let's do a like a sample code directory. And I want to I want to check this sample code directory for some file. And so we'll call this, like, "objective.js," and in here I'm gonna be doing I don't know, let's say a want to export a financial, and that function is just going to return, right? So, effectively just want to validate that I did this properly. There's a file. Exports a function. That function puts out the string boop. So, I know how to write tests for this. How do I make that dynamic? How can TwilioQuest find this file and check it for me?
MARGARET: So, Ryan suggests that you look at the validator examples for reference, because so, like I mentioned, in order to check code that people have run, you need to know where to check it. So, generally, we break this up into multiple objectives so or you can have it be multiple answers on the same objective, but you have to first know where to look and then what to run and then you can run it. Now, we tell them what to name it, but we let them tell us where to put it, because not every operating system is gonna put things in the same place or do we want to constrain people in that way.
JASON: Okay. So, let's see. This one's for Python.
MARGARET: And so generally, we will ask somebody for the full path to the directory that we will then look for all future code examples from.
JASON: Okay. Extensions directory. URL. Let's see. You passed the trial of reusability. I love it. Okay. So... I'm probably just scrolling right past this, but I don't see the part where I set somebody do they just put it in as a string or is there, like, a file browser?
MARGARET: No, they put it in as a string.
JASON: Okay. I gotcha. I gotcha. Okay. If I'm gonna do that, I can do something like in my objective for objective 2, the first field, which I'm gonna need to look at this one for, has a name of, like, "source_code_path," is there a pattern for these? Am I doing something horrible by doing snake case?
MARGARET: No, because you're the one that's gonna be referencing it later.
MARGARET: I mean, I guess we can at some point create a style guide, but I don't think that's been top of mind just yet.
JASON: So, it would be path/to/your/code.
MARGARET: Oh, and Ryan mentions that we save the file path as an environment variable, which the first objective validator example has.
JASON: Save it as a here's the example. Am I looking at it? Helper.success here. Okay. So, this is setting it as an environment variable?
MARGARET: That looks like output to me.
JASON: Yeah, what is I'm not quite sure I understand.
MARGARET: No, I see. So, the first part is the output, and then the second part apparently is environmental variables here.
JASON: Okay. Okay. Okay. So, it makes an environment variable. Okay.
MARGARET: Oh, okay. So, apparently all of them will have the prefixed TQ_, and then whatever is in the name will be the rest of that environment variable. I see.
JASON: Got it. Let's see. Where are you writing code on your computer?
MARGARET: You can reference that variable in all subsequent validations. Thank you, Ryan.
MARGARET: Ryan thinks that you might be mixing common js and es6 module syntax.
JASON: Absolutely possible that I'm doing that. Let's see. I am, because I need to get see, out here, this would need to be exports or we can so, that should work because now that's that's all common js. And then here in my validator, these are all common js, I think, right? And then I need to assert. Which I shouldn't have deleted from my import. So, I'll just get it back here. I want to assert that boop equals boop. And let's see how that actual check goes here. Oh, so, we're going to try assert.strictEqual. I did this all sorts of wrong.
MARGARET: Chad is suggesting module.exports instead of exports.
JASON: Well, I was doing it as a named one, but okay, chat, if you want to do default exports. Sheesh. Yeah, that's fine. Let's do that. Okay. So, then we've got this. We're going assert.strictEqual. Function does not boop if that happens. So, threat CI speaking wait, where did I just put this? Did I put this in the wrong one? I did. Oops. Okay. So, we'll undo this one.
MARGARET: This is why we recommend that you be very descriptive when you're naming your extensions directory and that you only work on one at a time.
JASON: Yeah. Okay. So I think I think this should work, as long as I put in the right file name. So, let's get back in here and give this thing a try. (Footsteps)
MARGARET: Let's see what breaks.
JASON: Okay. So, if I go oh, boy, let's just run the PWD here. Get this one. And then we want it to be sample code. So, that should find the boop.js. Probably.
MARGARET: Ryan thinks that the syntax for environmental variable setting isn't quite right.
JASON: Definitely possible. Hacking. Still hacking.
MARGARET: Yeah, I
JASON: I'm assuming I broke it.
MARGARET: Do you want to open up the developer tools and see what your error is?
JASON: Ooh, what a great idea that I wouldn't have thought of. Cannot find module. But why? That exists. No, it doesn't. Because I called it objective.js for reasons beyond comprehension. Fine.
MARGARET: What are words even?
JASON: Okay. Can I restart it?
MARGARET: You can potentially warp to the same level. But you might have you might have to close and reopen.
JASON: Let's warp to the same level. I let's see. You told me warp! And then I go to vr_mission_template player_entry1. These are just the default values. We don't want to go to Space Garden. We just want to go right here, right?
MARGARET: I think, yes.
JASON: Badow. Okay. That's a good. That's a pro tip.
MARGARET: That's why that's why I asked Ryan to lurk in the chat, because he has all of the pro tips because he is the pro.
JASON: Okay. Let's go pwd again. And I'm going to copy this. And this one should go to objective. Okay. You can access my downloads folder. I did it! Aha! We did it! Excellent! Okay. So, now we have the ability to kind of write whatever code, have somebody put in their valuables or their , like, the location of it. Put in their valuables. You know, wallets and watches into the bag, everyone. So, we can now have them add in this this variable. So, I got this wrong, though, Ryan. Let me go check let me go check the docs again. Tada. No, this one? Yeah, this one.
MARGARET: Yeah, I thought you were just on it.
JASON: Yeah, so, name and value. I did that wrong. Name and value. Okay. So, that should give us an actual environment variable.
MARGARET: Which you can then reference for all of the other objectives that you're definitely gonna add to your custom level.
JASON: So, now if we break our code, let's make sure that it still catches. So, let's try again and see if it does the thing. I need to reload it. Let me
MARGARET: I always get excited when I see the success.
JASON: I mean, I'm also excited. Although in this case, we're trying to make it fail. Hey, thank you for the sub, TammyClaps. (Footsteps) Okay. Show me a failure. Ugh, okay. So, I missed a piece. Because it should be
MARGARET: Ryan thinks that require might be caching in a way we don't want.
JASON: Uhoh. I don't even know how to do that.
MARGARET: When all else fails, exit the game and open it back up. That's always my strategy. It's the equivalent of turning it off and back on again.
JASON: All right. Let's try that again. And oh. Ryan, I can't do that. I can't eval. You're like that's just me begging to break your game.
MARGARET: Or your computer.
JASON: Or my computer.
MARGARET: So, you skipped past this because we are doing a specific thing today, but if you had gone through the progression in the game as a normal player, you would discover that one of the first things that we make you do as a player is promise us that you understand that running code on your machine is dangerous.
You hackers. You dirty hackers.
JASON: Yes, absolutely. (Footsteps)
(Beep) Okay. This time it's gonna work. There it is.
MARGARET: Oh, no.
JASON: We did it. We did it. No, I think this is great. And then Eco brought up a good point which is that we can probably just, like, query string it and then fix it. And then we'll go back. Let's reload. (Footsteps)
(Beep) Okay. Something with the caching is definitely not quite doing what we want, but that's okay. Because we know how to fix it. We just start it all over again. Okay. So, we are we are coming up on time, so, for someone who wants to go further and do more, what would you recommend is a next step?
MARGARET: So many things. Okay. So, I definitely recommend anybody that is interested in playing or writing levels for TwilioQuest, head on over to our forums because we have an amazing community of humans that will help you on your learning journey, that will help you on your game dev journey. It's just a great group of people to be tapped into. So, highly recommend that you check that out. You can also head over to the Twitch.TV/TwilioQuest channel, where we stream every Tuesday at 9:00 a.m.. Every other week is a developer stream where Ryan and I talk about either whatever you have requested we talk about and demonstrate or whatever we feel like. If you haven't made many requests that week. Then every four weeks, we have our Education Partnerships Program stream. Then every four weeks we have an event stream. Next week is an event stream. We will be streaming for four hours. We'll be raising awareness and funds for an awesome nonprofit that does amazing community work. That is also a great place to ask questions and get instant feedback. Weapon always have somebody playing and somebody hanging out. So, that means somebody available to answer your questions, if you have them. You should also make sure that you have that link to the docs for extension authoring. And also, let's see, what else? What else, Ryan? Oh, Discord. Yes, of course. You shed head on over to the Discord. If you prefer chatting to more longerform interactions, we have a Discord. Also, if you would like to experience all of the cool stuff that Twilio has to offer beyond our educational video game. I highly recommend you check out our annual conference that is happening in October. That is Twilio SIGNAL conference. If you happen to be an underrepresented developer, the scholarship program is for you. You should absolutely check that out as well. I guess that's it. Questions, comments, concerns?
JASON: Not from me. That was excellent. I it's always fun when the person who comes on the stream is also a streamer, because we like both wrap up for each other. No, this was this was so much fun. I think this was excellent. I, you know, am continually impressed just by Twilio as a company. I think the breadth of things that Twilio does is impressive, and I love that investment goes into, like, making a video game to teach people how to code. That maybe doesn't seem core to Twilio, but I think that it's cool that the company understands how much this stuff actually helps and makes an impact and improves the community. So, I love to see that investment go there. I'm really, really excited to see the work you're doing on it. Thank you to you and the rest of your team who hung out in the chat today. Y'all are wonderful. Chat, make sure you go and follow Margaret on the tweeter. Get on there. Do that sub on TwilioQuest. Make sure you go and do that one. Today, we've had live captioning all day thanks to Jordan from White Coat Captioning. Thank you so much, Jordan, for hanging out with us today. That is made possible through the support of our sponsors. We've got Netlify, Fauna, Hasura and Auth0, all kicking in to make the show more accessible to more people, which means a lot to me. While you're looking at things on the site, make sure you go and check out the schedule because it is just it is just off the wall, y'all. It's so much good stuff coming. So, we're going to do CSS grid container queries. I'm downloading Chrome Canary so we can use some future CSS. We're going to do TensorFlow on Friday. That's a special time. We don't usually do Fridays, but we're going to do one this Friday with Bekah. We're going to learn about using machine learning TensorFlow. You're being UI and UX. Team workflows in Notion. Next in Contentful and GraphQL. So, so many good things that you can come in and learn. Make sure that you click that Google Calendar button so that you get it added and you can see what's going on. Don't forget, if you're not already, make sure you follow and subscribe to Learn With Jason. With that, I think we're gonna call this one a success. Margaret, thank you so much for your time today.
MARGARET: Thanks so much for having me. This was fun.
JASON: This was an absolute blast. All right, chat. Stay tuned. We're going to go find somebody to raid. Margaret, thank you. We will see you all next time.