Intro to Lua for people who know JavaScript

Learn With Jason S8E9 Apr 17, 2025

Lua is a scripting language used in everything from games to embedded systems to Wikipedia. Potch teaches us why it’s cool and how to get started.

Read the transcript

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 LENGSTORF: Welcome to another episode of Learn With Jason. Today, we are going to dig into something exciting. I've been excited about game dev recently. I like the idea of building games. I find it really fascinating. It's a part of programming that always seemed too hard for me. So being able to demystify that a little bit and get an idea of what game programming is and how similar, or dissimilar it is, is something I find interesting and valuable.
Today, we're going to learn about a programming language called Lua. Lua has been used in a lot of popular games. It seems to be a place where it shines. We're bringing on a JavaScript developer, who has been learning Lua, which is� sorry. [Laughter]. Who just took over my screen there for a second and threw me off. Please join me in welcoming to the stage, Potch.

POTCH: Hello. Sorry about the click there. How are you doing this morning?

JASON LENGSTORF: I'm doing so good. I'm so happy to have you on the show. We're going to be talking about Lua and dev. Can you give us a bit of a background?

POTCH: Yeah, gosh, doing frontend web development professionally for 20 years. Kind of writing JavaScript for about as long. Was at Mozilla as a web platform advocate, did developer advocacy for Glitch and spent time working at Splice, which is a music technology company and I just started to break out on my own, to pursue and independent game dev. I'm based out in Mountain View, California.

JASON LENGSTORF: Very cool. Very, very cool. So, talk to me a little bit about your programming journey. I assume� you told me, as part of this, that this is going to be Lua for JavaScript dev. I'm going to make the assumption that you started as a JavaScript dev. Is that an accurate assumption?

POTCH: With only the slightest detour� I had access to a crappy laptop with 16 shades of orange and DOS and QBasic. I've been making terrible games for a very, very long time. Mostly for my own and my sister's, but, yeah.

JASON LENGSTORF: You know, I love that. I think there's something magical about making a game that's just for you. You're not worried about mass appeal or whether or not you can explain the rules to somebody you never met. You get to do something that's uniquely yours and that's playful for you and the people you care about.
So let's talk about� I guess, so you kind of made the� you made the jump into web early on. You talked about working at Glitch, you worked at Splice, which is a music platform. How did you end up in game dev now? Where did that turn happen for you?

POTCH: In 2020, unfortunately, it was a pandemic layoff. I was laid off at Glitch, along with other folks. I said, okay, I've been doing developer advocacy for a bunch of years, what would you like to do next? Well, I've always wanted to make games. At the time, I was so burned out. It was 2020, other things were going on. So it just didn't feel like the right time. I was like, it's a thing I'd like to do, but I didn't have a plan. I was like, I'm going to go get a job. I joined Splice. I started laying groundwork and doing experimentation and the inspiration the Playdate. If you go to the play.date website, you can pull that up, too. It's an independentlymade handheld Indy game console, made by Panic. Recently got into game publishing. They did Fire Watch. They made this really cute, little handheld Game Boy thing, with a crank on the side and they were like, sure, we're going to publish a bunch of games but it's going to be a public platform. You can grab their SDKs. The middle path was Lua. And I was like, all right. I think I really want to try making a game for this. Let's see what Lua's all about and that sort of led me to dip my toe� I've written other programming languages other than JavaScript. If I can write something in JS, I'm going to write something in JS. That includes messing with Electron and playing with all� playing with progressive web apps, trying to get to as many platforms as possible.
I was like, okay, let's try writing� let's try picking Lua up and I had�

JASON LENGSTORF: Let's do this for real. Let's see.

POTCH: I had heard of Lua. It's the canonical, oh, you know, there's some game that supports mods. The mods are written in Lua. It's always been this sidecar language through these platforms and popular games.

JASON LENGSTORF: And it's in� it's in a lot of stuff. What are some of the things that are powered by Lua that we may have heard of?

POTCH: I� you know, I even pulled up a little list here. Some of the stuff that� you're like, oh, it was scripted by� I don't know if you people were playing with Gary's Mod, which was a halflife to Sandbox. It's in everything. You can control Apache web servers. Its whole pitch is you want to be able to customize that world or write their own plugins extensions, it's like the canonical scripting language. Tons and tons of engines use it for extension by users or even customization within the game, which is really, really fun.
Trying to think of other big things. I would say that one of the current hot things is Balatro. It was written in Lua. In fact, using the AI game framework, which is what we may talk about a little later.

JASON LENGSTORF: Very cool. I've been playing a lot of that game. I don't think I'm very good at it. [Laughter]. But, yeah, yeah, yeah. Sonic Astro in the chat is saying World of Warcraft has a lot of Lua, that is a fact. But, yeah, lots and lots of good applications for it. Lots of things out there, that we've probably used. But so, as a JavaScript developer coming over to Lua, how did you find the onboarding experience? Like, what felt� what felt familiar and what felt different?

POTCH: Yeah. One of the neat things about Lua is despite its design, I think the whole compiled runtime is 270 kilobytes. It's unbelievably small. It seems to� it managed to express a fairly highlevel language and so from someone who comes from the JS world, it's an embedded language. It's not strongly typed. I'm sure people have feelings about the goodness and badness of that. It has the same scoping concepts. It's a lot of syntactic translation, but not expressive translation. You can do most things you want to do in JS or over in Lua. It was mostly kind of a� it was a, okay, what syntax am I writing today?

JASON LENGSTORF: Got it. That totally makes sense. That's always good to here. One of the things I've noticed about the programming language experience is when I move to a new programming language, because of the experience I've had in JavaScript and the PHP I did before that, it feels less like I'm stepping into an unknown world. Everything feels familiar. It's like going into someone else's house. You feel a little bit less lost when you walk into a new programming language, after learning a first one.
But it is always interesting to find out which ones really familiar, like, which programming languages have the same taste as the people who wrote JavaScript, versus the ones where people think very differently, when you walk into something like LISP. It doesn't feel like writing JavaScript at all. [Laughter].

POTCH: Sure. What's interesting about Lua� Express is a highlevel language. You're fighting against memory but you're not allocating memory, like C. You're able to be fairly expressive in a fairlyconstrained runtime environment. Sure, you may have to� you may have to, you know, do a lot of testing to make sure you're not writing things that are super slow or whatever. That's no� nothing� I think we're not familiar with. Especially if you're building for people's mobile phone and things like that.

JASON LENGSTORF: Yeah. I can see why, if the runtime compiles down to 275 kilobytes, why Lua would do a target for game devs because if you want to throw Balatro on an Android device, it's very large. To be able to comfortably say, I know the thing I'm about to build is going to be objectively small. It's not going to take up a lot of space and that at least means� you can make something slow, but it's starting you off on a good spot, where you have a good chance of kind of being fast by default, which is�

POTCH: I personally definitely can make anything slow.

JASON LENGSTORF: I have an uncanny ability, I can make anything slow. [Laughter]. I feel like I have a lot of questions that are starting to feel like syntax questions which probably means it's time to look at the screen. Let's switch over. Let me get my screen shared with the chat here... this is the one...okay. And so, first and foremost, let me give a quick shoutout to a brandnew sponsor and this one means a lot to me because I have both been the person hiring and the person making applications and so I know how much hiring� just the whole hiring loop right now sucks, in generally. It's really, really difficult to get a job right now. It's really, really difficult to hire right now. You're getting hundreds, if thought thousands of applications. To skim through those and give an assessment is borderline impossible. I have been really impressed with the team at G2I. I've heard from recruiters�it's usually, hello, we think we have an interesting opportunity for you here. G2I are people I have met. They understand the space. They have a huge list of alreadyvetted engineers that they're ready to pair with companies that are hiring right now. If you're a company, if you're trying to hire, the process of working with G2I is really, really pleasant and they're doing the work of screening people, taking them through technical assessments and doing the resume screening. It's G2I. I'm going to drop a link in the chat. This link is very long. So, please copypaste it out of the chat. If you talk to them, let them know I sent you and get great engineers without spending your entire life skimming through a pile of resumes. It'll save you a lot of money to work with a good recruiter. Thank you, G2I, for picking up sponsor to the show.
It makes us possible to have live captioning. Our live captioning is being done by Vanessa from White Coat Captioning. Thank you, Vanessa. You can find the captions at lwj.dev/captions. So, thank you, again, for being part of this, making the show a little more accessible to everybody. Let's talk about Potch. You can find Potch on Potch.me. And I also think you should go and click on all the social profiles and follow wherever following is a possibility. We're talking about Lua today and so I'm on the About page of Lua today. This is the most programry. It looks like it's been used in Adobe Light Room, Angry Birds, in World of Warcraft. It is all over the place in the world� I've used a lot of apps that I'm finding out are powered by Lua.

POTCH: Absolutely.

JASON LENGSTORF: So, that takes me through my spiel and into my question I love to ask, which is, Potch, I have no idea what's going on, what should I do first?
[Laughter].

POTCH: Let's get Lua. It is not there by default.

JASON LENGSTORF: It's certainly not there. Pop up a terminal?

POTCH: Pop up a terminal. You're going to brewinstall...

JASON LENGSTORF: Brewinstall Lua?

POTCH: Yep.

JASON LENGSTORF: Auto updating Homebrew.

POTCH: The part that's updating should be faster.

JASON LENGSTORF: That was a very fast auto update. [Laughter]. Okay. So, I now have Lua so just like a which Lua, there it is. Lua/v to get a version?

POTCH: I believe. Oh, you nailed it.

JASON LENGSTORF: There you go. All right. We're running Lua 4.5.7, which I assume is the latest, as of today. I'm ready to rock and roll.

POTCH: If you want to make a file, we can run it periodically and see what we're getting.

JASON LENGSTORF: I'm going to make a directory. We're going it call this "Lua for JS devs." We're going to end up sharing all this and let me open this up...I'm still in an empty folder.

POTCH: Love it. Let's make a main.lua.

JASON LENGSTORF: Right. Main.lua. This is probably going to ask me� or probably going to encourage me to install�

POTCH: Looks like you may even have an extension. It recognizes you're in a Lua syntax mode.

JASON LENGSTORF: Lua� did it really? Oh, it says� okay. Let's see what it does without it and we'll install the language server after.

POTCH: Let's get the most important business out of the way, let's print "hello world."

JASON LENGSTORF: Is it a parenthetical?

POTCH: Let's use the parenthetical and quotes are� strings are quoted. Yeah.

JASON LENGSTORF: Is it double, single, does it matter?

POTCH: Both work.

JASON LENGSTORF: Is it a semicolonterminated language?

POTCH: It is a semicolonoptional language.

JASON LENGSTORF: Just like Java! Good. Good. [Laughter]. So, to run this, then, do I just Luamain?

POTCH: Nailed it.

JASON LENGSTORF: Look at us go! I'm officially a Lua programmer.

POTCH: So, obviously, you can see, in terms of calls� function calls and strings and basics, it's going to feel very� it's very� you know, hard to tell from Java or Python. It's very, very, you know, straightforward. Yes, you� as you started typing that dash, doubledash is the comment syntax. That doubledash and text is how you make comments. So if you see that�

JASON LENGSTORF: That is a comment.

POTCH: Bingo. The other important thing is, Lua is a sort of firstclass language, which means everything is� everything can be saved as a variable, including functions, much like JS, you can store reference to a function. Variables are global. Which, in a lot of embedding context, is usually on purpose because, hey, let's declare all our variables up top and allocate all our memory. For what we're doing today� I would say, generallyspeaking, it is maybe the biggest sort of, you know, snare, but is making sure you declare your variables and make sure you don't have typos because they'll become magical global variables. You declare variables with the word "local." Global is default, "local" is instead of var or whatever. If you want to say, "local name" or whatever the heck we're going to�

JASON LENGSTORF: Okay. So do one of these.

POTCH: And we can write "function. "Boom, you got it. And then, the�

JASON LENGSTORF: Why don't we do one of these?

POTCH: Boom. Yep. It does not have curly braces.

JASON LENGSTORF: No curly braces. In this case, does it still return?

POTCH: It's still Return. They use something� a string concat operator, which is doubledot. I think of it as PHPish in that way.

JASON LENGSTORF: I've never seen that.

POTCH: You end definition functions with "end."

JASON LENGSTORF: Okay. So, then if I want to say, "hello," like that, that should theoretically� heyyyy! Look at us go! Okay. So, so far, this� this feels� this is the first thing that throws me. Everything else I feel is familiar, makes sense.

POTCH: The concatenation is different, for sure.

JASON LENGSTORF: I understand what's going on. We haven't had any errors yet, which feels maybe for� we're saving them up for later.

POTCH: We'll get there. Don't you worry. [Laughter]. You know how in JavaScript, everything is an object?

JASON LENGSTORF: Yes.

POTCH: Lua has a something similar. A construct is a table. The table is outside of boolean string, function, number, "table" is everything else. It is the data structure. So, tables are both function as arrays, indexed numerically, as well as objects that are sort of hashed and much like JS, they are curly bracebased. So if we want to make a list of numbers, you would�

JASON LENGSTORF: A list of numbers, okay.

POTCH: Or whatever, okay.

JASON LENGSTORF: We want to do a list of numbers, I can do something like this?

POTCH: Exactly.

JASON LENGSTORF: Okay.

POTCH: Maybe we want to iterate over that or something that may be the way to go.

JASON LENGSTORF: Yeah, let's do it.

POTCH: Forloops are a little different, as well, iteration is done� iteration, the way you introspect a table uses this� functions to unpack things for you. So for this case, we would say if we only want the value� let's try. If you say "for number" or "for N in numbers," and then "do." Within here, we'll be in our loop body.

JASON LENGSTORF: Okay.

POTCH: We may find ourselves in an error case here. There's a little subtlety here that I'm flying by wire.

JASON LENGSTORF: So let's find out. We'll just run it.

POTCH: If it doesn't work�

JASON LENGSTORF: Attempt to call a table value�

POTCH: For iterator. I believe we can say "pairs" around the word "number."

JASON LENGSTORF: Like so.

POTCH: Exactly like that. What that's going to do is create a key value, almost Tuples. So what we can actually say is for� oh, and that did log.

JASON LENGSTORF: Ooohh, we're getting the index.

POTCH: And also, Lua is oneindexed.

JASON LENGSTORF: This was intentional to show the difference between the index and the number. I saw somebody giving me hints in the chat.

POTCH: What we can do is say, "for index, n," for no wrapper. There's implicit destructuring going on in the language that is kind of nice. Now we get our stuff back.

JASON LENGSTORF: If we wanted to do both...

POTCH: Uhhuh.

JASON LENGSTORF: Do something like so and then we get our one index, first value, index value. Okay, great.

POTCH: Boom! Nailed it. Now we're looping. We've got, you know� and you can� I'll start with the other type of tame, which I think you went to start to make a person. Let's do that real quick.

JASON LENGSTORF: Okay, we got ourselves�

POTCH: We're going to do a key value syntax. They use "equal." Otherwise, you're going to find it familiar.

JASON LENGSTORF: Commaseparated values? Okay. That's probably fine. And, okay. So, then if we want to do something with that, we� I would say, um...is it this?

POTCH: Both accessor methods and dot syntax and Sugar both work.

JASON LENGSTORF: Okay.

POTCH: There are definitely differences, but a lot of your instincts are going to serve you well.

JASON LENGSTORF: As someone who knows JavaScript, I'm intuiting my way.

POTCH: Lua is a prototypebased language, which means that sort of by default, there are no classes. We live in the era of 2025 where class sugar has been added to the language of JavaScript, but fundamentally under the hood, it is sugar. Lua, by default, does not shift with any class structure. But they have this whole concept of metatables and metatables that act as the parent or superstructure of a table. If you've ever� remember the days of making prototypebased classes, it may have been a minute.

JASON LENGSTORF: I do remember. I just� I feel like some� some suppressed memories just awakened. Is everybody watching my eye twitch?
[Laughter].

POTCH: Let's make a Person class very quickly. Let's make a capital P Person. That is� you done it. So, that's is the toplevel thing. If we'd like to give that a� if we would like to give that a, um, some default values, we totally can do that.

JASON LENGSTORF: Um...we kind of don't want them�

POTCH: Deceptively simple and a couple other things we're going to have to do to get it fully wired up.

JASON LENGSTORF: Okay. So, we could� I guess, the things that would be interesting here are, um...like, as we get into more progressive stuff, like, you would say, like, you track somebody's age�

POTCH: Uhhuh.

JASON LENGSTORF: And they're going to have a birthday every year so you want to increase their age. Do we want to get into that kind of thing?

POTCH: We will get into that momentarily. We're just going to create a default object to start.

JASON LENGSTORF: Okay.

POTCH: We can put things here.

JASON LENGSTORF: Our default object is just going to be "alive."

POTCH: Love it. Perfect. Now we're going to� you know how we� in JS, there's prototypes where you can climb the tree to find the properties of the parent, right. If something isn't on the default, it may be on the parent. Lua has some constructs for that. One of them, which is a special property called doubleunderindex. For Person� sorry, not for, as in the word. Persons.doubleunderindex. We're getting into a specialty default.

JASON LENGSTORF: We made that selfreferencing for reasons I don't quite understand.

POTCH: When we take a Person object later and we want to check status, it will look to see if that is� what this is doing, under the hood, this is sugar for the metatable that when you try to get a key off the thing, will try to climb the parent object. There's a lot we yadayada'd. Trust me, bro. [Laughter].

JASON LENGSTORF: Good. Good. I'm ready.

POTCH: We'll say "functionperson.new." This is a function. We can take any� this will be any� so, we'll declare this, just like we declared any function. The name is "person.new." Precisely.

JASON LENGSTORF: Something like that. Was it colons or next line?

POTCH: It's just the next line. So while we're inside, get a little strange. We're going to create an object that has the fields that we want it to. There aren't pure constructors. It would be equal to age. We're going to� because this isn't a true constructor, we're going to return the new person...so, we call this� we have to return. The other thing we want to do is we're going to set its metatable and we're going to say, "set metatable, all lowercase, confusingly. And that's going to� we're going to set New Person. And set rect. Not rect, Person. Sorry. I have an example off to the side here.

JASON LENGSTORF: More magic.

POTCH: We're saying, hey, its metatable is this thing called Person. So now we can create new people and they will have the fields that we set, as well as the fields that are on the prototype.

JASON LENGSTORF: Okay. So if we want to do one for me, um, is it�

POTCH: It'll be person.new. There's no new syntax here.

JASON LENGSTORF: I just realized I'm outing myself.

POTCH: Hey, 39 club. You can also� we can do numbers, if you'd like.

JASON LENGSTORF: Oh, we can do straightup numbers.

POTCH: Like JS, numbers are numbers.

JASON LENGSTORF: Got it. Okay. So then we can do something like "print..." I did it!

POTCH: Crushing it. Let's add a method to our thing.

JASON LENGSTORF: Let's do it.

POTCH: Above our, what we had before our declarations� below or constructor. This is the one other sort of squirrely thing. We're going to say "person:And the name of the method." This is syntactic sugar. What that's doing underneath the hood is that is going to give us a� an object that is "self" and that is Lua.

JASON LENGSTORF: Got it. This would be self.age+=1.

POTCH: Uhhuh. And you'll call it with the colon, as well. This is the thing that always trips me up, remembering to call instances with instance methods with colons.

JASON LENGSTORF: 0ohhh. Okay, so...and then we would do "Jason have birthday."

POTCH: Uhhuh.

JASON LENGSTORF: And then we can copy this...and run it again...I screwed something up.

POTCH: "+=" might not be valid. I think "++" will work.

JASON LENGSTORF: I'll try it again.

POTCH: It might be "=+11."

JASON LENGSTORF: No shortcuts in Lua. There we go. Okay, so that's doing the thing and then if we� just to make sure it is, in fact, doing exactly what we could expect.

POTCH: Should not have aged.

JASON LENGSTORF: Yeah. So, same, my object ages, yours does not and we get the expected output, objects are contained. That's� cool, that's very cool. I'm with it. We are doing� we are doing the thing. Look at us go.

POTCH: You've learned what I would describe as the bones of Lua. The only other things we may want to look at is tables. The default shipping API does not have any really classes in it. They have global methods for table manipulation. There's a global thing called "table" so you would say, "table.insert" and pass the thing or table.� you invoke the global table helper.

JASON LENGSTORF: I would do, like, table.insert and Jason�

POTCH: This will push a value on to a list. If you want to add a property, you can use the�.syntax.

JASON LENGSTORF: Got it. If we have something that's, like, local� we'll say� we'll say "people." Start as us and then down here, we want a table� no, we'll create a new person and we'll say Marissa and that is� no, what is that? Person.new.

POTCH: Uhhuh.

JASON LENGSTORF: Marissa and... [Laughter].

POTCH: Age�

JASON LENGSTORF: "Table.insert" and it would be "people.marissa" and then down here, if we do a "for..." "index people." We would print "person.name." We're going to get three names...it doesn't because I did something wrong�

POTCH: Not a colon. It would just be the word "do."

JASON LENGSTORF: Oh, right, right.

POTCH: Totally fine.

JASON LENGSTORF: Now what did I do?

POTCH: Now what did we do?

JASON LENGSTORF: Attempting to call an iterator.

POTCH: This is the pairs, the goofy thing that�

JASON LENGSTORF: Oh, right. Right. Okay. So, now we've� we have added� we've made a list of people. We've added a person. What if we wanted to drop off? What if we want to remove me from this table?

POTCH: There's a "table.remove" that takes an index.

JASON LENGSTORF: And that would be one in this case, right?

POTCH: Uhhuh.

JASON LENGSTORF: Yeah.

POTCH: Yes, that's correct.

JASON LENGSTORF: So now the list should only� I screwed up. I didn't save. There it goes. We're doing the thing. We got it going.

POTCH: I would say that you� your Lua 101 badge is earned. And since you have talked about wanting to do game stuff, I think this is a point where maybe we pull down a GitHub project that I've made.

JASON LENGSTORF: Absolutely.

POTCH: The first thing I want to talk about is sort of the� there's the Playdate SDK. When it came to wanting to build games that could run on desk top or things that are not a wonderful, quirky, handheld console, I was looking at this game toolkit called Love 2D, or Love, which is a Luapowered game framework, which is really, really lovely. This is a Brazilian language, which is really, really cool. I saw some comments in the chat about that.
If you go to the README, we have a set of instructions for you. So we're going to install Love 2D, which is a thing we do not have yet.

JASON LENGSTORF: I'll go and grab this. This�

POTCH: That's the one.

JASON LENGSTORF: So we're getting Love 2D.

POTCH: Feel free to put thing anywhere in your directories. We will need the path.

JASON LENGSTORF: What the hell did I just do? I want to move...

POTCH: You dragged into Adobe.

JASON LENGSTORF: I don't want to do that. I want to drag it into Applications. There we go.

POTCH: The good news is, if you put it there, we should just know where it is. If you go to package.json, let's see...I did not, look at me. Wonderful. The other thing we need to do is do an npminstall. You don't have to, using an "on change" autorestarts things. Great. Boom! Here's our little world that I built for us.

JASON LENGSTORF: Wow!

POTCH: I remember, there was a recent� a past thing I watched where you were talking about specifically your fear of collision detection so I've done the service of writing a rectangle class with collision detection implemented and we can maybe build a small game on top of this.

JASON LENGSTORF: This is great. So, okay, so what is happening here. We've got 26 lines of code.

POTCH: I'll talk you through this. The first thing you'll notice is that Line 1 is requiring a second file, Lua does have sort of have modularity. You can do modules of exports. Lua, the base language, does not. I've written us a rectangle class here, that just has a constructor that lets us set x, z and height. That looks familiar to what we wrote for Person. I have a Draw method. Love implements something akin to the Canvas API so we can do something more fun. It's creating a rectangle and using the rectangle information to� the rectangle information from our object, to draw.
And then I wrote two methods� whether a rectangle contains two points or intersects with a single rectangle.

JASON LENGSTORF: Got it. What is Contains?

POTCH: If any x, y point is greater than the left side, less than the right side�

JASON LENGSTORF: This is our edge detection?

POTCH: Whether a single point is inside of a rectangle and it is testing each side of a rectangle to see if it's inside of a rectangle and it tells us if those rectangles are overlapping. When we turn bright green, that is the Intersects method turning True.
If we go back to our Main file, that was the first thing, the creation of that rect. I'm loading an image. I'm doing maybe a little more magic here than is needed to quite understand. But the first thing is the most important, Line 3 is I'm loading an image and once I have that image, I can draw it. Maybe we can find ourselves a cool spaceship.

JASON LENGSTORF: This corrects at tiles.

POTCH: I'm sort of creating this concept called Quad, which now we're getting into GLE. There's a larger rectangle that's going to be the size of our screen and it's going to repeat at the image "get width" and image "get height."

JASON LENGSTORF: We get a new rectangle located at 200 pixels tall?

POTCH: Correct. If you write a method called love.draw, it will be called every frame and so this function is�

JASON LENGSTORF: Okay. That's slick. That's nice. It does the frame detection for you. In the previous stream that we did with Will King, which I guess if we should mention that, I should probably bring it up, let's go to CodeTV and then...here's our TypeScript game engine...and so, you can go watch that, if you want to see how we made that work. Let's get back into the code here. We had to write our own loop and do some math to make sure we were running at framespersecond.

POTCH: So, one of the nice things about Lua is� there are a lot of ways Lua is much like JS. Lua is really all about what the embedded environment brings to the table. Right. In Node, JS has all these interesting builtin superpowers around access and the DOM APIs bring stuff around creating HTML elements and making network requests. Similar things, but it's all about the provided runtime around the language, so Love is bringing a graphical and game engine set of APIs to the Lua language and Lua's really, really good at effectively letting you� people effectively implement an API in C or another language and embed Lua into it and provide hooks and provide all those things as an API within the language.

JASON LENGSTORF: Got it.

POTCH: Love.draw is provided by Love in to the Lua global scope and saying, hey, if you make a method, we will call it. And you can do what you'd like.

JASON LENGSTORF: I understand. So then why� we get in here, we set our graphics color to white?

POTCH: That is white. You intuitive correctly. It is 0 to 1, plus alpha.

JASON LENGSTORF: And this, we're drawing our image, which is the background, inside of our quad space and we want it to start at the topleft and I don't know what this is.

POTCH: Here. Let's tweak that second� the third parameter, in third zero. Type a number there. Let's see what it does. No harm...

JASON LENGSTORF: Oh, it popped open for me again. That's cool. I broke it.

POTCH: Maybe make a small number,�.01 or something like that. Let's see. I'm actually curious. It's slowly rotating the quad, that's a rotation parameter. It's in radians. You can probably�

JASON LENGSTORF: What are radians? �.1.

POTCH: The topleft position, the rotation and then the last two things are a scale factor so we put 1 as the scale factor.

JASON LENGSTORF: If I make this�.5, it is going to scale it�

POTCH: I think you put�.0.

JASON LENGSTORF: Sure did. Got to stop trying to tab out. That squishes it to half the width of our space.

POTCH: The quad stuff, I wanted a pretty background and I was like, it's worth it.

JASON LENGSTORF: Worth it!

POTCH: The next couple lines are getting our mice position. You can see the syntax, you can return xyz.

JASON LENGSTORF: Are those� they're unpacked by named parameters, right? It's not ordinal?

POTCH: Correct. It is ordinal. Sorry.

JASON LENGSTORF: If I do Return 1, Return 2, Return 3, I can let favorite number, leastfavorite�

POTCH: You'll return it and collect those.

JASON LENGSTORF: Okay. Got it. Cool. So, then we take our exposition. We go 20 pixels to the left and top of that and make it 40 pixels. We set the color to� what is this� RG green, which I could have determined by looking at the screen. [Laughter]. Oh, wait, that isn't right.

POTCH: This is the larger rectangle.

JASON LENGSTORF: Larger rectangle. Okay. If it intersects, we draw the fill. Otherwise, we draw a line. The dude is drawn at red. Okay. I understand. Cool. Okay. This is� this all makes sense to me. My� my� my ability to understand this code was stronger than I expected.

POTCH: Part of that is, once you know a language, reading other languages are somewhat doable. I feel like Lua really does have enough� like I said, is this lowlevel language with really highlevel syntax that feels pretty good.

JASON LENGSTORF: The abstractions in Love are really nice. I can imagine this would be a little gnarly if we went and looked at how Draw is implemented inside of Love.

POTCH: Very fortunate that that is a box that's remained closed to me. Let's see about making a game. Let's� or, maybe even something simpler, where let's say if you're� if when we intersect, maybe we move the rectangle.

JASON LENGSTORF: We can push it around a little bit?

POTCH: Push it or move it around. Something lightweight to start. When we intersect� maybe we'll fill it that once. Afterward, maybe we'll move it.

JASON LENGSTORF: Move it somewhere else and then maybe just to make this a little easier to move it around, we can make this smaller.

POTCH: For sure. Basically, we generate two new random positions for it. Like, a new random xy and we move it.

JASON LENGSTORF: Right. So these need to be set�

POTCH: We can update them in our�

JASON LENGSTORF: We could do� we could do a start� current x and that's going to be 100 and current y is going to be 100. And so, we can�

POTCH: We can do it that way or we can manipulate or x or y.

JASON LENGSTORF: Oh, straight on the� ooohhh, that totally makes sense. An r�

POTCH: Yep. Uhhuh. And we'll just assign that. It's all lowercase. Math.random. It has a helper for our� by default, it is 0 to 1 and you I say, comma, width� the size of our rec, so 40.

JASON LENGSTORF: Got a little bit of magic numbers going, but that's okay.

POTCH: Our rectangle is 40 pixels wide, so we don't want it to hang off the edge. We could actually say� let's make them not magic.

JASON LENGSTORF: What a brilliant idea.

POTCH: There's much less magic and with� minus r.height. Boom!

JASON LENGSTORF: Now, what we should say. It'll flash and in next frame will appear in a new location. Boop, boop, boop, boop. Look at us go!

POTCH: This is maybe more of a [Indiscernible] visionlevel game more than anything but there's something here, right. We could maybe say, maybe we don't want to touch the rectangles or whatever. We have options.

JASON LENGSTORF: Now it's becoming less about, can I do this thing and more about what should the thing do. So, we're getting into the part of, like, game design, which is very different from game programming. Right.

POTCH: Yeah. We have� I feel like we've got enough basics here, we have graphics on the screen. We have logic and our frame. Let's add one more� let's add one more� one more little� we're going to add one more method outside of love.draw.

JASON LENGSTORF: Okay.

POTCH: I'm doublechecking it's going to be� we can write another method called "function." Function.love.mousepressed." That will take arguments, that will be x and y. There's a button one. We'll say any button. x and y are the only arguments we need.
Let's take that intersection text and copy it down here. Let's say you have to click on the rectangle to sort of make it move, right. And we'll remove all the drawing stuff because this is only� this is a pure interaction function. And up above, we can remove the� we can remove our test� our moving logic. Cool. So now we have to click on the rectangle.

JASON LENGSTORF: I can highlight it, but nothing happens�

POTCH: If I wrote the code right. All lowercase. Magic names. Oohhh. And rectangle. Oh, I believe, "Dude "or "r."

JASON LENGSTORF: Rectangle is�

POTCH: Confusingly, I think it's complaining about "dude," which is created inside of our love.draw. We should raise that to the other thing and set it as xy, as the mouse position.

JASON LENGSTORF: Attempting to do arithmetic on global x�

POTCH: Those should be 0, 0, 40, or something like that, on line 9. That's its undefined variable method. We'll set the "dudes" x and y.

JASON LENGSTORF: I need to bring that back.

POTCH: Exactly right.

JASON LENGSTORF: Where's the x and y?

POTCH: Those come from the mouse position.

JASON LENGSTORF: Dude.x equals x; dude.y equals y.

POTCH: Is it still not working?

JASON LENGSTORF: This is where we had to do the math to take it minus 20. So, we're going to take it by half, which we could do the math to figure it out on�

POTCH: Totally.

JASON LENGSTORF: Bam! Look at us go. When I click...now we have actual interaction. So, this is great. It's� like, it doesn't do anything yet, but honestly, you could call this an idle clicker game. I feel like I've played games like this.

POTCH: Let's draw text to the screen. Let's make a score number somewhere in our toplevel scope. Let's put a little text on the screen.

JASON LENGSTORF: We'll start with a score of zero and then down here...we want to say...can I just do� what's our score? It's going to be� our dude is a new rectangle.

POTCH: Score� much like the Canvas API, there is a direct draw text called Print. Love.graphics.print.

JASON LENGSTORF: Print. And then this�

POTCH: I believe� maybe� because we don't have Love. The text first and then x and y.

JASON LENGSTORF: Score will be "score." And our x, let's maybe make it� for easy math, let's go 1010. I don't want to have to calculate it from the right. [Laughter]. We'll do that. And then in here, if intersects, then we can do "score equals score plus 100." So it's pretty small. You can see it.

POTCH: It's red because it's the last color we set.

JASON LENGSTORF: You're right, you're right. So let's fix that. We're going to make that right so now our score is white and as we click, it goes up by 100 for each click. Look at us go! And then, oh, you know what we could do, also, because we got this "else" in here, if you are bad at clicking, take away score. I click, I click, I click and then I click outside and it goes down.

POTCH: Ooohh, I like that.

JASON LENGSTORF: So now it's like an accuracy thing. If you miss, you lose points. Some fun to be had there.
Okay. We've got scoring mechanics. We're feeling our way through this. [Laughter].

POTCH: I mean, hey. You're getting close to be a certified game dev here, in my opinion.

JASON LENGSTORF: Look at me go! So, I mean...this is great. So, what do we next? What's the right...I guess, where would you go next? Like�

POTCH: Where would I go next? Gosh, I think it would be cool, personally, for us to� let's make a table of these rectangles, that we want to click, and let's� let's see� maybe have them moving around the screen.

JASON LENGSTORF: Oh, yeah. So, maybe we could step this. We could do, first, let's make a table of the rectangles and when you click it, it removes them. You're trying to clear the screen. And then we can have them move to increase the difficulty of clearing the rectangles.

POTCH: I like that.

JASON LENGSTORF: So that'll help me, too, because it makes a little more bitesized to put it together. So, instead of�

POTCH: In our setup� actually, I'm� we're playing a little fastandloose. Love does offer love.load, that sort of lets you do loading in there. Setup could happen in there.

JASON LENGSTORF: Okay. But we don't need�

POTCH: We don't have 250 do that. The top scope is fine.

JASON LENGSTORF: What's the benefit? Like, why would you use that versus doing it in the top scope?

POTCH: I believe that Love, I think, has eventually some ways of saying� the game is loading, we can show a thing when it's ready. Right.

JASON LENGSTORF: So if we were doing something intense, loading a leader board from a third party, you would have a loading state.

POTCH: This is such a lowlevel game engine, right, we could have a function called Game and that function is called� and we could have a function called Main Menu. We could say, are we drawing the main menu? Are we drawing the game? We could have effectively states. It is only the gamegame part of our thing, but you could imagine a menu with a start button. When you hit the start button, then it switches to calling the function that calls the game.
For now, we can just keep going like this. We may just want to create as opposed to one local R, a single rectangle, we can iterate over a count and add a bunch of rectangles to a table.

JASON LENGSTORF: Okay. So, let's do that. So, we've got our rectangles and what I want to do down here is I want to say, local...we'll say targets. I want to iterate over a list. Now, is this something you do shorthand or do I create a table.

POTCH: Let's create an empty table. There is a construct that we can use, that we haven't used yet. So, how many targets do you want?

JASON LENGSTORF: Let's start with 10.

POTCH: Okay. For 1, 10�

JASON LENGSTORF: My brain just broke. What happened?

POTCH: That is a� let me very quickly get that� the numeric "for" statement. It is effectively has�

JASON LENGSTORF: Index...start. Max and what's the last one?

POTCH: So, it's actually "for i equals."

JASON LENGSTORF: We're starting at 1.

POTCH: Counting to 10.

JASON LENGSTORF: And the step is one at a time.

POTCH: The step is optional. It's implicitly 1 if it's missing. And now we could say targets and create rectangles. We can use our random numeric generation to put them in random places on the screen.

JASON LENGSTORF: And to do that, that was somewhere down here.

POTCH: Because the rectangles, we don't know their width and height, we might have to use�

JASON LENGSTORF: You know what? We should, but we won't.

POTCH: Also fine. [Laughter]. Love it. Cool. So now we'll have 10� we can iterate over those targets and draw them.

JASON LENGSTORF: Okay. So we've iterated over our targets and then down here, instead of...this...we need to make this, like, a for� let's see...for, uh, we're not going to use the index, but we are going to use the target.

POTCH: Uhhuh.

JASON LENGSTORF: Of pairs.

POTCH: I believe it's "for in." That's JS versus.

JASON LENGSTORF: Doubleend. We're going to switch out or Rs for targets.

POTCH: Uhhuh.

JASON LENGSTORF: Okay. Let's just see� okay. So that gets us a lot of the way there and then in our draw, down here, we've got our R. So, this is going to need the same thing. We're going to need to loop over our targets?

POTCH: For 10 targets, this is plenty efficient. When you get into very large numbers of things, having to iterate, it starts to get expensive. We are far away from that being a problem.

JASON LENGSTORF: I can always see a problem.

POTCH: It misses� yeah. Misses true and set it to false� if you hit anything, right?

JASON LENGSTORF: How is this going to work? So what we need is�

POTCH: Misses by default, true. Your instinct was deadon. We take out the� say "miss equals false."

JASON LENGSTORF: Okay. 0hhh, and down here, we have to say, if miss equals false� oh, no� if miss equals true�

POTCH: I believe it's a doubleequals for comparison. Yeah. And it's a "then" instead of a "do," which is confusing.

JASON LENGSTORF: Aahhh that makes sense. Score minus 100 and then we end and now� so, counting this up, we're saying, by default, you have missed the target. As we loop over these targets, if you are intersecting, that means you did not miss so if you click� all of the targets loop and you didn't hit any of them, that means you did, in fact, miss the targets. Otherwise, you gain points and you're winning the game. The other thing we need to do is when we hit, we need to remove this. So this would be�

POTCH: Oh, very good point. Now we want that index. In the other loop, we didn't care.

JASON LENGSTORF: We do want that index, correct. Is it table.remove?

POTCH: Table.remove.

JASON LENGSTORF: And targets and index. Look at me go. Okay. So now when we're over here. We go, we click. My "remove" didn't work. But...oh, and my misses are definitely not working, either.

POTCH: Let's take a moment and see what we goofed on here.

JASON LENGSTORF: If R�

POTCH: It's Target. We have our old static R declared up top. We'll get nice errors instead.

JASON LENGSTORF: Bam! Look at us go! We're clicking machines. That's it, perfect score. 1,000 points.

Perfect score, no misses. But then I can ruin the thing because we don't have an end state when you're done.

POTCH: Blast yourself into the negative. If you'd like, we could put an End state.

JASON LENGSTORF: Knowing we're about 20 minutes from the end here, I think I'd rather get movement than an End state. You check whether the targets are empty, if so, then you would kind of, like, draw something new on the screen that says, you win. Or, like, you know, game over, final score. That part, I get that. That makes sense to me. But movement, so far...we have not� we haven't even talked about. So, how does one do such a thing?

POTCH: So I will admit, for now, we're saying, hey, we've been doing everything, every frame. If you were doing movement truly correctly, you'd be using Delta Time. For now, let's just have these moved by some amount every frame. Does that mean they'll jitter a little bit, yes? Does that mean we don't have to spend a bunch of time doing delta time math, yes. [Laughter].

JASON LENGSTORF: I imagine delta time is documented in the Love 2D docs.

POTCH: Yes. We'll leave it for the sophisticated game developer. We can, within our existing target loop, move them before or after. I would say, moving them before would be more respectful. So let's� let's� let's just do classic. Let's do classic, like, Microsoft Windows, you know, bounce� DVD logo logic, let's just do� give them a direction x and a direction y.

JASON LENGSTORF: Okay. Yeah.

POTCH: By the way, let's make them an object. Let's say they have� when we push, let's make a table that has a field called Rect. So, right in our table� Line 14, we're going to push a curly brace that has a field called Rect. Right. And we can� we'll close that. We may want to it on a new line. But we'll also give these a DX and a DY for a direction.

JASON LENGSTORF: Okay. Direction X�

POTCH: Let's make that math.random negative 1 to 1. Do you want them to all be moving diagonally.

JASON LENGSTORF: If they hit zero, then it would just be going straight up and down.

POTCH: We have options here.

JASON LENGSTORF: Let's do that. That makes sense, because I didn't even think about that.

POTCH: Then we can do DY. We'll have to update our logic to say�.rect.

JASON LENGSTORF: Everywhere we do target like this�

POTCH: We could make a true class, again, right, for...

JASON LENGSTORF: As this grows, we'd probably want to look at that.

POTCH: 100%. The fact that we can make these oneoff things is also quite nice.

JASON LENGSTORF: Target rect. And then here, we've got�

POTCH: Those will also be target.rect. Yeah.

JASON LENGSTORF: Okay.

POTCH: That all looks good.

JASON LENGSTORF: Let's just doublecheck that I didn't break anything. Is doing exactly what we wanted it to do. Okay. Perfect. That gets us going. Now we have the direction. We can randomize.

POTCH: Uhhuh. So now we should be able to, in here, just set� increment our x and y by the amount...and if we hit the edge, we'll invert it, which is probably my instinct.

JASON LENGSTORF: Uhhuh. Check for, um...check for edge...change direction, if so.

POTCH: And here, you know, let's give ourselves a little leg up. Let's going to the top. We're going to create a rectangle called Screen that is the 0x0 width height.

JASON LENGSTORF: 0, 0 width height. Now we have our screen so we can check if the x or y value is less than zero or greater than screen.width or screen.height.

POTCH: What we can say is, hey, are we no longer inside of this rectangle, right. Or we can say� if the new point, or if I new position would be outside the rectangle.

JASON LENGSTORF: Okay. So, our� our movement distance, we can say, is going to be five. That feels like it's fast enough we'll notice it. But not fast enough we won't be able to catch. We could say the� the target.rect.x is going to equal target.rect.x plus target.dirx times� and we'll say five, so that's kind of our distance there. We can start here, as a way to just see whether or not is, in fact, moving things the way we want it to go.

POTCH: 100%.

JASON LENGSTORF: Also, that is fast as hell. That's a little more doable. Right. Okay. So, one pixel at a time, 60 framespersecond.

POTCH: This is why delta time is truly important. [Laughter].

JASON LENGSTORF: So that feels good. I'm happy with this. But, we haven't got our edge collection. So then we have our new rect, x and y. So how would you calculate? Is there any penalty for me setting this twice?

POTCH: What I would probably do is create a new x/new y value, test that and set it if it's good. You know what I mean?

JASON LENGSTORF: That seems reasonable because then we're not messing with stuff. We won't get jitter that way.

POTCH: Yep.

JASON LENGSTORF: If New X�

POTCH: In our screen� our screen has a� rectangle has a Contains�

JASON LENGSTORF: New� how does that� is it just pulling off the x and y off the dude?

POTCH: You pull in a new x and y point. It will be Contains.

JASON LENGSTORF: New X/New Y.

POTCH: It has a thing to adjust the bounds of the screen. We'll take a look at that in a sec.

JASON LENGSTORF: Sooooo, New x� width minus the target width because right now, they're going to bounce out a little bit. So if it contains it, we want it to do that.

POTCH: We can set it, uhhuh.

JASON LENGSTORF: So we'll say, target rect x equals new x. And�

POTCH: Yep.

JASON LENGSTORF: And New Y�

POTCH: The happy path is simple. The lesshappy path� we want nice logic. We want some "ifs" because we want to know if it's going out the top.

JASON LENGSTORF: Is there an "else/if"?

POTCH: If the New X is greater than� yeah. Greater or equal to because the Contains is strictly less than. Target.directs equals target.directs. We'd do that for the lessthanzero case.

JASON LENGSTORF: Okay. So, we do�

POTCH: We can say, New x is less than zero.

JASON LENGSTORF: Does "or" work like that?

POTCH: Yep. The words are "or" and "and." We'll do the same thing for our Y case.

JASON LENGSTORF: Then we've got our y. That's going to be height. And we'll change all those to y.

POTCH: Let's give it a run. Let's see what it happened. There's a good chance they're going to fly off into infinity. We need to subtract 40.

JASON LENGSTORF: We do, but look at this! We're doing it. So, this is perfect. So, we have our� the intersection, here, and our screen just needs to be minus 40 because that's the width of our targets. That should make our intersections a little better, there they go.

POTCH: Now I want this for you, which is, I would like you to, very quickly, if you're able, find a little graphic for our� our� let's see if we can't find ourselves a little spaceship or something.

JASON LENGSTORF: How do we find one that's� are there any that are legal to use?

POTCH: Right.

JASON LENGSTORF: I don't want to get rid.

POTCH: Let's see if I can't find you something real fast. I should have had this in the project for you.

JASON LENGSTORF: Freepik, are these royaltyfree? Pixabay does this? That's not even close to what we were after. [Laughter]. Eightbit spaceship.

POTCH: I know Google Search used to have a tab.

JASON LENGSTORF: What if I fly the space shuttle. I'm going to download�

POTCH: We may need to shrink that bad boy down a bit, but I love that.

JASON LENGSTORF: That is fine. I can pop open one of these. What size do you want it to be? Like, actual size?

POTCH: This is for us or for our targets?

JASON LENGSTORF: This is for us, so 40x40.

POTCH: Let's make it 64x64...

JASON LENGSTORF: We'll bring in our spaceship here. [Laughter]. And then we're going to make that...64.

POTCH: And if it's not exactly�

JASON LENGSTORF: This is going to be fine.

POTCH: If we have a way to knock out the background.

JASON LENGSTORF: I believe there's no background on this. Yeah, there's not. We're going it call this "spaceship." Okay. And then did you want a bad guy?

POTCH: You want an asteroid, a flying saucer, what are you feeling?

JASON LENGSTORF: I think I saw...

POTCH: Close enough.

JASON LENGSTORF: It's fine. And here, we need another one of these.

POTCH: We make these a touch smaller...

JASON LENGSTORF: And this is going to be target...these will be, what, like, 32?

POTCH: Yeah.

JASON LENGSTORF: Drop that out of here.

POTCH: I guess 40x40 is our thing. We can do whatever we'd like.

JASON LENGSTORF: We're in charge. All right. So, that is also exporting without a background.

POTCH: And we can drag those right into the project.

JASON LENGSTORF: Okay. Right into the route.

POTCH: Yep. If you saw how we loaded that initial image. The good news is we're not trying to tie this. Load them using the New Image command.

JASON LENGSTORF: So we've got our spaceship and our UFO.

POTCH: In our current drawing� our dude should be 64x64. We may want to match the aliens, as well.

JASON LENGSTORF: Oh, man, this is going to get a little goofy because we�

POTCH: This is our click target. We're going to work around this temporarily.

JASON LENGSTORF: Okay. So, our dude is 64x64.

POTCH: And where we were drawing the dude.

JASON LENGSTORF: And that is going to be down here.

POTCH: Very bottom, I believe. We want to set the color to white. When you draw images, it takes the color into account. We'll want to say love.graphics.draw. Instead of dude.draw, we're no longer drawing our rectangle. We're going to say love.graphics.draw and say "dude." [Indiscernible].

JASON LENGSTORF: I called the graphic "spaceship."

POTCH: We've been moving that minus some amount. Say dude.x; dude.y because we're keeping it in an account.

JASON LENGSTORF: That is the minus� is 30�

POTCH: I don't think we need the minus because I think the rectangle already did the minus. I believe we set the minus when we set our position.

JASON LENGSTORF: Great question.

POTCH: Yes, minus 20, minus 20. Now we're getting into� a lot of magic numbers. Hey!

JASON LENGSTORF: Look at us go, we're a spaceship. Okay. So, same thing here. We can do love.graphic.draw.

POTCH: And this one, we just need the topleft, because we're just tracking the topleft. Target.rec. Now we have hit boxes and graphics. We can decide, well, you can decide whether to draw the hit box or not.

JASON LENGSTORF: Let's leave the hit box off, but we can maybe change the fill...I broke it.

POTCH: Our UFOs are not showing up. Is that right?

JASON LENGSTORF: Yeah.

POTCH: What format was the graphic?

JASON LENGSTORF: They're all PNGs.

POTCH: Is there a log.

JASON LENGSTORF: I probably screwed something up here.

POTCH: If it's a weird PNG.

JASON LENGSTORF: What did I do wrong here? Spaceship, UFO. Love.graphics.draw.

POTCH: Make sure the color's set correctly.

JASON LENGSTORF: That'll getcha. My UFOs are not showing up. These are not the best...is it because I'm trying to draw the fill?

POTCH: Um, yeah, I would be surprised, but...

JASON LENGSTORF: Not it.

POTCH: I wonder if that PNG file is just being� let's doublecheck. Target.png and you loaded that up top. Let's doublecheck you loaded that right. Looks great.

JASON LENGSTORF: Called UFO. That's the only place we touch it.

POTCH: Temporarily, change it to the other thing and see if it draws. I just want to see if it draws.

JASON LENGSTORF: It shows up there. Oh, oh, oh. So, basically what we're doing is�

POTCH: We are drawing over top of it, also.

JASON LENGSTORF: I know what I broke. We are drawing over the top of it, but we should�

POTCH: You can just swap the order here. We need to draw it no matter what, you're right.

JASON LENGSTORF: We need to draw it, no matter what, is the problem. There's our UFO. There's our graphics. This is not� let me put this behind.

POTCH: Yep. And then we can delete the line for a moment.

JASON LENGSTORF: We picked a really bad graphic, the same color as the background. Oh, damn, this is really hard. [Laughter]. Where's our� you know what, I think we might have made this game impossible, because I can't actually click so something in the detection is wrong, but, we got things going. We are out of time. So we're going to� we're going to have to kind of call this what it is. But, like, I'm really impressed by all this. We got so much further than I expected us to get in terms of using Lua because I thought we were going to kind of learn some syntax and maybe see� the stuff that we did in the first few minutes is what I thought we were going to do in the entire show. To get all the way through� if I could figure out hit boxes� my targeting is weird. We've got a whole game going. Scoring, hit boxes, movement, enemies, graphics, very good stuff.
Potch, where should people go if they want to learn more? While you're thinking, I'm going to throw up some links to your personal stuff.

POTCH: Yeah, they want to learn more, first of all, this project, as we picked it up, is available on GitHub. I will happily� Jason, if you want to make a pull request. Starting with our� what I'm going to call Jase Invaders.

JASON LENGSTORF: Boooo. [Laughter].

POTCH: I'd love for people to play more with this. Offscreen, I've had the Love 2D Wiki and the Lua� lua.org/manual, which are the fantastic docs for Lua and Love and referring to those offscreen and talking you through things because as much as I've been learning this stuff, you know, textbook's open is the way to go. Create a fork and create a PR and I'll merge it all in.

JASON LENGSTORF: I think that just did the thing. Repository not found.

POTCH: Pull request. Hey, look at that.

JASON LENGSTORF: Look at us go!

POTCH: And we're doing open source contribution.

JASON LENGSTORF: Here's love 2D. The Wiki's linked there. The Lua docs. This is in the notes. You can find all this in the Discord, the CodeTV Discord, which I'll drop a link to that, since I'm talking about that. There's a Show Links panel. Let's get that in there. And, with that, that is� that is all we had time the today. Thank you, again, to G2I. Thank you to Potch for hanging out to us. Thank you to all of you for watching and supporting. Make sure you go check out what's coming up on the show. We've got� next week� not next week, I'm in London. We're going to have Brad Frost on the show the following week. If you're curious, come learn about it. It's useful and it'll show up in your working ways you may not expect.
We are just cooking� we're cooking today. Potch, any final words before I shut this down.

POTCH: One of these days, I'm going to show up on one of your other programs. That's all I'm going to say. Keep checking me out at Potch.me. I'm going to be posting my game development journey there, at some point, if I ship something, I'm sure I'll be a huge pain in the tookus and tell everyone.

JASON LENGSTORF: Thanks so much. We will see you next time.

Supporters

Become a supporter to see yourself here on future episodes!