DAVID MALAN: Hello, world. This is the CS50x Educator workshop, and this is our session on how to teach CS50G, or CS50's introduction to game development with CS50's own Colton Ogden. And indeed, what I love especially about how Colton architected this class is how every week of the class is structured around one particular game, but then he looks underneath the hood at the underlying academic and design principles that underlie the functionality of each game. Colton, the floor is yours. COLTON OGDEN: Awesome-- thanks so much, David. But yeah, let me go ahead and share my screen here just to make sure that we have the slides being shown while we get started here. Hopefully everybody can see that. So yeah, as David, said GD50, Introduction to Games, is a very visual course. It was something that, like Ramon said, really started me on the path of programming. I really loved games growing up, and I decided to learn programming because I wanted to make games, and that eventually turned into a lot of other areas of computer science that interest me now, including web development and other areas. But yeah, GD50 was designed to be a very visual course, a very project-focused course, a course that does take a look at a lot of really famous titles that a lot of us have probably seen in this room. And thanks again to everybody for attending. Let me just make sure that I can see all the participants and the chat as well. I encourage everybody who has questions to please ask questions as we go along. This will be a very conceptual overview of all of the lecture material in the course. We won't be diving too deeply into a lot of the technical details, but we will take a look at the concepts that we teach throughout the course. If anybody has any questions to lead us in, I'd be happy to answer them, but if not, I can take us into the intro to the course. And so thanks again, everybody, for tuning in today-- got a lot of stuff. Love the gaming chair. So does Joseph. Thank you very much. In the meantime, let's go ahead and start. So the syllabus for the course-- a lot of you probably see a lot of really famous titles here. I love games. I've loved games since I've been two years old, or even younger maybe. And in particular, a lot of these games are games that I grew up with-- Super Mario Brothers, Legend of Zelda as examples. And David also grew up with an NES and with some of these titles. But we also have games like Flappy Bird, which are games that were as young as-- 2012, 2013 was when that came out, I believe-- a lot of games that are simple and iconic, because when I was putting together the outline for this, it was trying to find what games had that mix of both really easy and-- conceptually to understand, at least from the top down, but also being exciting-- because that's a big part of this course is trying to get people's appetite whetted week to week, and keep things moving along, keep things from getting a little bit too stale and dry. So a lot of different interesting games here-- some games that are 2D throughout the first 2/3 of the course or so, up until Pokemon, and then after that, we start going into 3D with Unity. Andre's saying, loved games since my past life-- agreed-- same thing with myself. So the course is split. It's a 2 to 1/3 split intentionally, because this course is intended to be an intro to both 2D and 3D games. So on the left side of the slides there, you can see Lua and the Love2D icons. That's the framework that we use for the course. It's an excellent framework-- very easy. It's got a great API. And we use Lua because Lua's actually a very industry standard programming language for game development. It was initially intended to act as a glue layer for higher level-- or for large-scale compiled applications, like C and C++, but then, because game engines in that same vein-- especially the '90s-- operate in the same way, where they're large compound code bases and it's hard to compile them, Lua ended up being a great language to use for scripting game logic that didn't require recompilation. And so we use that. It's used in the modern games industry. A lot a lot of games are still modded and implemented in Lua, so for that reason, pedagogically, it's both sound and applicable to industry. And then, on the second side of the screen there, you C# and Unity, and Unity is actually probably the most used game engine now. I'd have to look at the stats, because Unreal Engine might have picked up a little bit of traction since 2018 when the course originally came out, but Unity for sure still maintains a very large market share, particularly in the mobile sector. But it's a fantastic engine, and it's easy to start using because it's not terribly hard to start putting together pretty simple projects. It's got a very nice layout. Everything is nicely organized, and it's got pretty much all the tools you need, minus a text editor, built into the engine itself. So we transition effectively from programming only up until the third of the course to really using more of a visual editor-- in a lot of sense, like the CS50 IDE, but even maybe less code-focused. So I figured, from this point on, we'll just go through each lecture one by one. We'll take a look at a little graphic of the gist of what the that lecture is, that game, and then we'll talk about the topics therein. And if anybody has any questions, I'd be happy to answer them as we go along. Joseph says, is there a way to deploy the framework using a high-level language like Python? There are game frameworks in Python. So Pygame is a very common game framework used. Python is not quite as used in the games industry as Lua-- just hasn't had that market share. It was used a lot in the early to late 2000s for a few games, like Civilization 4 was a game that I remember that used Python. But typically, in terms of dynamic languages, Lua is by far the most used. I've seen a few games that use JavaScript, few that use Python, but definitely Lua being the number one. But if-- pedagogically speaking, if you wanted to use Python, you could certainly tailor the course materials to using Pygame, because the API for Pygame is more or less in the same vein-- but good question. So this is Pong. So this is the very first-- and thanks, AJ, for tagging Pygame there. This is deliberately the first choice for a multitude of reasons-- one, it's very simple, and two, it's probably the most iconic game of all time-- maybe tied with Super Mario Brothers-- because it was really the first game that really took the games industry off. And obviously, Atari made the title. It was an arcade game, and then it became a home console game, and all kinds of different iterations-- but very simple. As you can see, there's paddles on the left and right, a little bit of text, and then a ball that moves around and collides with the paddles. So some of the topics that we end up covering-- obviously, we teach them the basics of Lua in this lecture. This is a great way to introduce it to them, because there's not a whole lot going on in the game, but enough to where they are making a full game. And then, of course, LOVE-- and in the lecture materials, we go over all the functions and whatnot that students actually use to get things drawn on the screen-- drawing shapes, drawing text. As you can see, really, all-- that's all there is. There's just rectangles. The ball's a rectangle. The paddles are a rectangle. The text in the middle of the screen is just text being drawn on the screen. There's an FPS marker up with the top left just to illustrate how students might be able to determine that. It's an important thing when you're testing games to make sure they're running smoothly. Additionally, things like delta time and velocity-- so this is how you measure how many milliseconds have passed since the last frame to this frame, which is probably one of the most important things with game development-- especially if you're trying to get things running consistently across multiple platforms, because if you're not doing that and you're just doing calculations, it's going to run as fast as the CPU s on a person's computer, which means that one person's computer versus another is going to run the game at variable speeds, even depending on what they're running on the side. If they have Chrome up, then the game's going to be slow, and if not, it's going to be running at whatever their native speed is. Things like game states-- so here you can see that we have player one's serve is-- briefly shows there, and they're waiting for Enter to be pressed. Games are an amalgamation of states-- whether they're playing the game, whether they're waiting for the Enter to be pressed because they're serving, whether it's a game over, whether it's the title screen. This is another very fundamental idea in games that really you need to exist in order to have a game to begin with, because you need to be able to transition to a loss or a victory state to really make it a game at heart. Things like object-oriented programming, which we don't really cover a ton in CS50-- but in this course, we do at least dive a little bit into object-oriented programming-- not a ton, but a little bit in the first lecture, we discover things like, what is a class, what is an object? And we use a library to make it a little bit easier than Lua is by default. And then, probably the crux or the fundamental bit about Pong that makes it work is box collision, AABB-- so being able to test whether two rectangles are overlapping and really-- really checking to see if they are possibly not overlapping, whether one left edge is beyond the right edge of another rectangle, and so on and so forth for all four edges will rule out whether there's a collision. And then that's how we end up deciding whether the ball hits a paddle. And also, we can test a similar idea really with the left and the right edge of the screen, checking to see whether the ball's right edge past the right edge of the right screen, and so on and so forth for the left side. And then, of course, sound effects, because what's a game without sound effects? It really does make a huge difference, in my opinion. Joseph says, yay-- or thanks. Yay-- OOP. OOP in game development in particular is a huge paradigm, probably the number one used paradigm in the world of game development. So if anybody has questions, that's Pong in a nutshell. That's the format we'll be looking at all the games, rather than going to technical today. But if you have any questions about any of that, I'd be happy to answer them, and if not, we'll go over to the next lecture. AUDIENCE: So my question is, what did you guys take into consideration when you designed the course, having projects in mind? Because the other courses also have projects that they spend some some more time talking about the concepts, and then, after two or three lectures, they tell the students to-- oh, take this project. But in game development, each lecture is a project, so what did you guys take into consideration? COLTON OGDEN: That's a good question. So with each lecture, we do cover things-- piecemeal concepts out of time. And most repos in the course do have a very basic version of the project that's just draw a rectangle on the screen, or print hello world in the middle of the screen to illustrate those concepts. But really, the design for this course was to keep things flowing week to week, and interesting, and very visually stimulating. And also, a big philosophy, or an aspect of my philosophy going into designing the course was to get students used to interacting with a lot of different large code bases because, especially with games, you will be looking at pretty large code bases, depending on how many games you're working on or what game you're working on. It's nice to be able to have that literacy. CS50 does have not insubstantial code bases-- they're pretty meaningfully large-- but this deliberately was to be a little bit more closer to the real world, I guess, in that sense-- what you might expect if you were open a GitHub repo on some game engine or some game code, and dive in, or even if you were to dive into a real game on your own and look at their own Lua config files or the like. Really, it was just to make it feel like you were really game programming, and also it was trying to accomplish building a course that I wish existed when I was learning, because something like this didn't really exist on the internet. You would typically have to buy a bunch of books or find a bunch of scattered around bits of code before you would find something cohesive, like a full project. So that was my design. Hopefully that answers your question. Why does assignment scoring take so long? I am not sure about that. I'm not actually involved in the assignment scoring, but that might be something to reach out to heads@cs50.harvard.edu or staff@cs50.harvard.edu. They might know a little bit better. Nitesh asks, is online multiplayer covered in this course, like hosting a server and people join it and start playing? That is not covered in this course. That's a little bit more advanced of a topic. And the course actually already is somewhat advanced. It can certainly be tailored. If you were to teach it in a high school setting or a middle school setting, you could tailor it by only maybe covering the Love2D lectures or the first four or five lectures. That would probably be a full course, and you could maybe spend two weeks on each lecture. But multiplayer, yeah, that would-- if we were to do a follow-up course, we'd probably do a multiplayer session. So thanks for the questions. So the next lecture is a bit of a departure. So the very first game, Pong, came out in the '70s. Flappy Bird came out 40 years later in 2012, 2013. And the beautiful thing about Flappy Bird is it is just so simple. And I think that was one of the things that-- aside from, I think, some shady marketing tactics that originally were coming out when the game-- initially came out and got the guy in trouble who made it. But that aside, the game is very simple and addictive, and very difficult. So it made for a great transition into the world of sprite-based gaming. We had Pong, which was just shapes and text, and then we transition into being able to actually have their own art. And I actually drew that bird, which was kind of painstaking because I didn't want to copyright infringe on the actual Flappy Bird artwork. But I got a chance to actually have a little bit of fun and draw that bird myself. The pipes, I think, I found somewhere else. But this is a great opportunity even for students if they want to import their own artwork, and start messing around, and get a feel for what it means to actually import sprites into a game. And sprites you might be familiar with from the world of scratch even, which is kind of a similar idea. So here are the topics that we cover in that lecture. So we have sprites, images-- so in the world of games, textures, which are the actual files on disk, and then you import them into your game, and then you draw them onto the screen, and they move around typically-- not always. And those would be considered sprites-- so textures being the art itself, sprites being the game entity-- the terminology for them. Infinite scrolling is something we look at because infinite scrolling is used all over the place in games. We actually use it to lectures here. We might use it in more. I'm not 100% sure off the top of my head-- at least two-- one of the Unity lectures and this lecture, which is just a matter of-- at least in 2D-- moving the texture and then immediately resetting it back to its default position. And if your texture is seamless, in that it loops within itself at a point, you can give the illusion of it moving infinitely. So here what happens is it goes a certain point, and then it just resets back to zero. But it has to be that sweet spot where you have a looping-- in this case, it's hills, so it's actually pretty easy to loop. But that's the gist behind scrolling textures-- very common in games, because obviously, you can't have infinitely large worlds. And that's part of the games are illusions lesson that I teach in this lecture, and that's a big deal with games, because games are, at the fundamental core, just tricking you into thinking that you're in some sort of world that doesn't exist using images, using sounds, et cetera. So we cover that a little bit conceptually. I show a video clip of a YouTuber that does a great job of showing some of these ways that game companies cut corners with their artwork when it's not-- when the user can't actually see what's happening. It's very cool, very fun. So you get a little taste of how that works in game development. Procedural generation-- so having things that are dynamically generated at runtime to create levels, to create other assets-- this is a very important topic now in game development, and it's something that's dear to me as well because I find it very interesting. So we cover that a little bit throughout the entire course-- this being just a very simple example of it, in that we have pipes that spawn at random, where they're-- the gaps are random and where they are on the screen is random in a way that makes sense. And this allows us to replay the game over and over and over again, but we don't actually have to hand code levels. And the levels can go on forever. Actually, all of it's done at compute time-- saves the programmers and the artists a ton of time so they can focus on the code and focus on the artwork, rather than having to focus necessarily on the levels. So if you can feed that into your game, that's a great lesson to teach. State machines is another important thing-- so the idea of being in the game state or the play state, which we covered in Pong. But we cover it in a little bit better of an implementation in this lecture. We actually use an object dedicated to maintaining the state of the game, and you can also take this and apply this to entities in the game. You can have characters that are in the run state, in the jump state. We'll see that in Mario coming up. And then we cover mouse input to a degree. We have very little mouse input throughout this course. We have two lecturers-- one on the Angry Birds lecture and this lecture we'll cover mouse. The majority is keyboard, but it's very important-- if students want to implement, say, a mobile game or a game that does use the mouse, having the ability to detect clicks and mouse movement is very important. Have you considered gamifying this class? Maybe turn some of the tutorials into a game. A game within a game class-- I haven't thought about it too much. Gamification, I think, is really interesting as applies to productivity. So personally, I-- if I'm trying to do something and I don't necessarily feel like doing it, I'll gamify things a little bit. I'll give myself a objective, which is to do something small or achievable within usually a 30-minute to an hour time frame, and then I'll reward myself with being able to do something that I want to do, for example. And that's what I think of with gamification. I'm not sure how it might apply pedagogically to teaching the course, but if you can find a way to make it work that's interesting, then yeah, I would say give it a try. Characters in the game are created using which tool? You can use any sprite editor. I use Aseprite-- A-S-E-P-R-I-T-E. AJ, actually, if you could pull up a link to that, that'd be super helpful. It's not free. You can use GIMP. GIMP is another great tool-- anything that's similar to Photoshop that allows you to edit rasters. So Illustrator probably won't work, although I think Illustrator does that you rasterize vector images. But we use everything as rasterized images, so things that have pixels-- RGB pixels-- in this course. And RGB color is an important part of the art of all of the lectures, because we usually do talk about coloring backgrounds and coloring other things. For example, in Pong, we color the paddles white and the background a blackish color. Yeah, AJ probably has some good pixel editors as well that he wants to share. But how is AI going to influence game development in the nearby future? That's a good question. So artwork generation, for example, has been sped up a bit by AI, neural networks, that sort of thing. I've taken a look at that a little bit and experimented myself. It's not quite at the stage where we can replace all artwork by real artists, and might not be that way for a long time, but I would expect that artwork and sound would be some of the first stuff to go-- and maybe some data processing. But the actual programming of games-- to have an AI be able to do that, that might be a ways in the future. We might start to see more visual editing of code, like we've seen in Unreal Engine's Blueprints system and Unity's Bolt system for visual editing of logic. That's going to be more common before I think we see AI doing any of that, any code generation-- but good questions. That was Flappy Bird, so let's go into the next lecture. So Breakout is a sort of evolution of Pong. You can see here, things are pretty crazy now. And this was a great use case of procedural generation to do something really visually interesting. So you can see there the map, the-- all the bricks at the top of the screen-- so the difference between Pong and Breakout being that, with Pong, you're two paddles facing each other. With Breakout, you're really just one player trying to destroy a bunch of bricks and bouncing a ball off the edges of the screen-- except for the bottom edge, because if it hits the bottom edge, you lose. And you can see the bricks have different colors. The colors mean that they have different number of times that they have to be hit before they can get broken. You can see particle-- we're using particle systems when the bricks get hit. So this is a much more visually interesting lecture than the last couple, where we do a couple of interesting techniques. Some of the topics we look at are sprite sheets being the first thing, and probably one of the more important things, as related to sprite editing. So a sprite sheet is really all of your artwork put into one file. So it can be cumbersome if you have a ton of different images. So if we're looking at this, for example, you can see that we have all these different bricks with all these different visual patterns on them. If you have a file for every possible brick, then you're looking at maybe 100, 200 different files-- different PNG files, and that can be cumbersome to deal with. But if you have just one file with a lot of-- all of the bricks laid out in a systematic way, you can write a function to actually split them out and import them as sprites to your game. And we show people how to do that using what are called quads, quad being literally just a quadrilateral. It's just a chunk of the texture that we blit to the screen using a particular version of the draw function that we use for everything else in the course for the 2D stuff. So that's what we mean also by procedural layouts with procedural generation. So here we have this layer at the top of the screen. This wasn't set in code. This wasn't set in a config file or anything. This was dynamically generated, and I show students how to do this using really just a set of a few simple functions and loops that choose random colors, depending on the difficulty that they're at. If they're at level 1 versus level 10, they should see a different set of bricks, different set of tiered bricks, et cetera. We talk about levels. So far, we've only had one level. In Flappy Bird, you have one infinite level. In Pong, your level is just the game board really. But with Breakout, you move level by level. So in the graphic here, when we get to a certain point, you'll see it say, going to level 32. Oh, I thought at least it did. Oh, it might not. I might have truncated it. But in this case, this snippet was taken from level 32. And if you beat a level, you get to go to the next level, and then to the next level, and to the next level, until you eventually lose. And it gets harder and harder, but you also get way more points. Player health is important. So at the very top right, you can see I have some hearts up there to represent health, which is a very common thing in games-- so being able to take not just one hit before you lose, but a few different hits. Particle systems-- again, just a visual-- just an aesthetic bit of spice to add to games. And those things add up a lot. If we had no particle systems here, really, that feeling of playing the game-- it wouldn't hit as hard. Those little things get taken for granted, but if they're not there, you notice them a lot. You'll notice the difference being some this unpolished and polished, and that's an important thing to talk about. I don't think enough pedagogical resources related to game developer really talks about that. We talk a little bit more about complicated collision detection, because we hit these bricks from all different sides, and the ball should bounce in a different direction, depending on where it hits that. So we cover a little bit more sophisticated of a collision detection algorithm related to AABB. And then we talk about saved data-- so being able to save high scores. So that's also another very important thing, a relic from the arcade era, if you will. But games today still do have scores. Flappy Bird is an example of that, where you're trying to always get a higher score. And games manage score in different ways. The amount of money that you've collected, the amount of enemies that you've slain, and so on and so forth can be used as different metrics to gauge your score, but the gist of-- the idea is to be able to save to your file system some file that contains your score, and then load it later so that you're always maintaining this persistent state. [INAUDIBLE] asks, what do you mean with AABB? So AABB is-- it's axis-aligned bounding boxes. So that's just a way of saying that you have two rectangles that are in Euclidean space-- 2D Euclidean space that are aligned perfectly, that you can just very easily gauge whether they're overlapping by checking to see if the edges of one are outside the opposite edge of another one. And if they are, then you know that you can't possibly have a collision, so that's how you quickly and efficiently check for 2D box-based collision detection-- good question. Are there open-source games that we can borrow ideas from? I've checked periodically. There's not a ton of fantastic open-source games. So there are cool projects, like there are clones of Minecraft and other games that are open-source that you can take a look at that are nice. I would go on GitHub and maybe just do a search for game. But ideas-- you can take ideas from any-- if you're talking about implementation-wise, it's going to vary. Your mileage will vary in that sense, because you might get games that are very beautifully architected, and you might get games that are not as nice. And I've definitely seen a mixture of both. But I would encourage you probably to find a game that you personally like and want to understand, if this is your goal, and look for an open-source implementation of it, because again, your mileage will vary. But use your aesthetic judgment when you're looking to these 2D code bases and understand that they're not always written in architected with elegance in mind. Some of them are. Some of them aren't. They might not always be the best teaching resources-- hence, another motivating aspect of creating this course. So after breakout, we transition to another very visually interesting lecture. So this is kind of a different take altogether. So Match 3-- people probably know this from Bejeweled or from Candy Crush-- very famous games, very addicting games, and a far cry from Pong, Breakout, and Flappy Bird. We're dealing here with a discrete grid of blocks and making discrete movements-- in other words, moving one tile with another tile to change some game state-- a very discrete layout of effectively numbers, and a small space of those numbers. And if they match in a certain orientation vertically or horizontally, then those get removed and filled with new tiles, and then we get to demonstrate a few cool visual techniques in the process-- things like tweening. So tweening is the process of interpolating movement across the screen. So here, I think-- for example, you can see, when the level thing comes down to the screen and then comes to the bottom of that, that's tweening. When the bricks there get moved and the tiles get shifted downward, that's tweening. That's tweening of motion-- very important with games, because a lot of game development is just interpolating movement between two different locations. So far, we've used velocity of something and calculated that, and adjusted its x and y position, but sometimes we don't want to have something using a velocity. For example, if we look at the start of this GIF after the thing comes down there, we have the level-- first of all, we have that white transition. That's a tween. That's an interpolation, but we also have that level text come down. Those are not dealing with velocity. Those are dealing with some number changing slowly over time, and we can use a few different ways of doing that. After that, we have solving matches. So that's a-- really looking at our grid, looking to see if we have numbers. We effectively look at our grid-- we look at it left to right, top to bottom-- and we just compare to see if we have three of the same match going in a certain direction, up until the second-to-last block, because that saves us a check. But really, if we have-- we know, if we have one pink, one pink, one pink-- and we check to see, left to right, if they're the same exact number-- then, OK, we have a match. Remove it from the board. Fill it in with new tiles. Add to the score. Carry on. Rinse and repeat. That's really all the logic that is with Candy Crush. And the same thing happens top to bottom too. You to a left to right every row, top to bottom every column, calculate all the matches, remove them at the end of the last movement, and then that's-- it's a very simple game loop but, very illustrative, and it-- since a lot of people love this game especially, they can make their own variant use their own tiles if they so wish. And again, procedural-- all of this is randomly generated. And there are ways that you can do a better job of this. We're using a few too many colors here, so there aren't really that many easy matches, but if you lower your number of colors, you can make a random grid, just toss run random numbers out there. Obviously, you're checking to see if there's any matches, and then get rid of them before you present the board to the user. But once that happens, that's all you have to do. And then you have infinite replayability and infinite-- you raise the difficulty by lowering their amount of time they have access to play the game, but after that, you're sort of done. And we also take a second to look away from game logic and take a look at the artistic side of game development. So you can see here, we're using a pretty nice looking palette of tiles and we're using a very finite set of colors. So we talk about color palettes. We talk about sprite artwork. Game development is largely a function of-- a successful game is largely a function of appealing artwork in addition to good logic. So you want to aesthetically be looking for something that's fun to play, that's stimulating to play, so that was a big goal with the course as well. Can we rope in, asks [INAUDIBLE], game theory or reinforcement learning techniques to design game strategy? Probably not in this course-- this course is a little bit more on the technical side of game development. Game theory, as it stands, is not even necessarily-- I guess, if you were designing AI, that would be a little bit more appropriate. Shouldn't AI do some behavior if some other AI is doing another behavior, and so on and so forth? That would be, I think, probably outside the scope of what this course teaches. And there's not really a lot of AI in the sense of reinforcement learning. Machine learning doesn't really get talked about much in this course, but I know [INAUDIBLE] course on AI, I think, goes over at least a little bit of that stuff. Oh, and also, AJ's telling me that the email that we're using should be certificates@cs50 if you have any questions about the grading of the assignments, and them taking too long to be graded. AUDIENCE: My question is-- I realized that most of the games-- they have topics and concepts in common, but also, every game, every project introduces new concepts. So my question is, how did you balance and how do you manage between taking for granted what the students have already-- you thought they already knew, and-- between that and introducing new topics? And what did you learn from that as a teacher? And my second question is, do you plan-- you guys playing on updating the course, just like you guys did with web programming and CS50 [INAUDIBLE]? COLTON OGDEN: So what I did is I assumed that effectively all students have at least some CS50 experience, because this course is designed to follow CS50-- or at least it should-- or some equivalent programming course. So I do assume that students have programming knowledge, but not necessarily game knowledge. That was a big deal for me, because I wanted this to be accessible for a lot of people and maybe get people interested in game development. So we really don't assume that people have spent a ton of their life playing video games or know a lot about video games, so you really cover things pretty conceptually slowly, but technically, we assume that people are able to put the building blocks together in a way that solves problems, if that makes sense. And it is a challenging course, and as far as if somebody has-- and this is something that I've learned-- if someone has not a ton of experience programming, this course can be difficult, so I would encourage this to be a follow-on course. Or if you're going to use it for your own curriculum, I would encourage you to try to, like I said earlier, maybe adopt a part of the course and go more slowly over it. Maybe interweave. If you wanted, for example, to have an intro to game programming, you could interweave CS50 with the games course piece by piece. That way, you keep students interested who like games, but you also give them the programming foundation that they care about. The course wasn't designed to be taught this way specifically, but I think it could be done so, if it were tailored appropriately and the pacing was appropriate. Maybe take a function of the beginning of the semester or trimester to talk about the programming logic and the fundamentals, and then spend-- and then start doing the interweaving approach, or maybe go full into game programming. The second question, which was about whether the course will be updated-- so the course will be updated this semester to use the latest versions of Unity and Love2D. Material-wise, it doesn't seem, at least to me, not yet that it needs content-wise an update, just given the fact that the course-- I deliberately designed it to be somewhat "timeless," quote, unquote. The framework itself may eventually die-- hard to say. And Unity might eventually go south as well, and then the new top engine might come out. But concept-wise, I tried to deliberately teach it at concepts, and that's really what you should do. If you're trying to take this curriculum and teach it to your students, you should focus on the concepts, and not say that, oh, Love2D is the number one way to get programming done, or Unity is the number one way to get programming done. Teach them about, what are textures? What are sprites? What is velocity? What is delta time? What's a state machine? These are concepts that are independent from any particular framework, and they'll help you give your students a better foundation-- not to get married to a particular technology but rather to understand things that are more fundamental base level. So good questions, Ramon. Thank you for those. Do you plan to include games similar to NetHack or Rogue? That's a good question. So we taught a version of this in the summer of 2018 at Harvard Extension, and I had to create a set of labs which were simple, very basic ways to get students a little bit of time outside the lectures to do more hands-on topics together, because the original course was designed to be a very lecture, project, lecture, project, lecture, project, format-- much like CS50 is. So one of those labs was a roguelike inspired project. I was just looking at it recently. I don't remember exactly what it was, but we-- I do like roguelikes a lot, and so I remember trying to incorporate that in some way. It's a very easy, basic thing to incorporate. There are libraries even for Lua that let you do that. rotLove is what it's called, if you are interested. I'll type the name of the library there. And this is a Lua library that you could use in conjunction with Love2D. If you wanted to create your own project, look up rotLove and give it a try. Are frameworks like Unreal Engine 5 hard to use, or can they be abstracted with object-oriented programming concepts? Unreal is a bit harder to use, and it's also a bit easier to use. So it's a bit weird. Unreal uses of visual programming system, similar to Scratch, but more feature-rich, called Blueprints. And this allows non-programmers to start programming. It can be nice. It can also be somewhat cumbersome, especially if you're more used to programming. If you want to code in Unreal engine, it's in C++, and it's-- it can be a lot to swallow at first. They use a lot of really long names for their classes, and static functions, and global variables. It's definitely challenging. It's for somebody who has a lot of industry experience, I think, to start diving into the C++ side of Unreal Engine. And Unity use a C#, which is similar to Java-- very similar to Java, which some folks here might have actually used or taught with. So in that sense, I feel like it's more approachable and easier to start using. I would encourage people probably to go that route for teaching a first course, or maybe just the Blueprint route. But in terms of a nice synergy between using a visual system and programming, Unity felt like, to me, the right choice. But that's a good question. If you were experienced or teaching more advanced course, you could certainly use Unreal Engine, I think, to great effect. Thanks for the questions. I appreciate the participation. All right, that was Match 3. So after Match 3, we take an exciting jump into the course-- or the lecture that really started this course. Really, this all happened at a workshop. We taught a series of workshops in the UK, and one of them-- David asked me to do a lecture on how to create a very basic version of Super Mario Brothers. And we used the original artwork for Super Mario Brothers for that, but for the course, we wanted to use copyright-free assets, so we used an alien mock sprite sheet, which looks really nice still, but it's obviously not the Mario that people know. But this is really a fantastic illustration of a lot of concepts coming together. We have our 2D artwork. We have animation now. You can see that the Mario character animates. He moves. He jumps. He has all these different expressions. Well, he's got a couple of expressions. They're a little bit hard to see because of the pixels. But you can see we have enemies walking around, a very simple AI where they just follow the player on the ground. We have blocks that can be interacted with that trigger different things. We have levels. We have procedural levels that are actually pretty feature-rich. If you're looking at this, it's simple. It's nowhere near the complexity that you might expect for a full game if you were to do a procedural level system, but all of this is randomly generated. The tiles are being chosen at random. The bricks are being put in random places. So we don't have to write a single file that has any level data in it. We just do everything in code. This is a very cool, fun project for me. It ticks a lot of boxes, and I enjoyed doing it. And this is the foundation of the course, I think. It shows a lot of really cool stuff. One of the big things we talk about is tile mapping. And actually, we looked at tile mapping in a sense with Match 3, because that's effectively what this. This is a tile map. This is just a bunch of numbers, and what we're doing is we're taking those numbers and drawing images on the screen at a particular location that matches those numbers. And then, to compare if we have a match, we're just looking to see if the numbers are the same. We're not really concerned too much with the visual aspect of it and using that for any of the logic. And here, it's the exact same idea. We have our map of sprites, but they're all just numbers. So for example, the ground is a one. If it's empty space, it's a zero. If it's that block with the exclamation point on it, it's a three or a four. That bush right there is a six or seven. It doesn't really matter. It can be whatever you want. You just have to be consistent with it. And then you can also decide to randomize-- rather than choosing one specific tile, you can say, I want you to pull from tile set 8 and use ID 8 of tile set 8, not the default tile or whatever original tile set you might want to choose. You don't have just one tile set. You've got 50 different tile sets, so therefore, you now have thousands, maybe even millions of levels that you could generate visually differently. So it was a fun lecture to put together. 2D animation-- very important. So you have a character which is now-- we're not only just blitting one image on the screen-- we're blitting a different image, depending on whether they're walking, whether they've been walking for 30 milliseconds versus 15 milliseconds. So that's what ends up swapping the frame of animation, and we just keep track of that and update it, and that gives them the appearance of walking around-- really just moving their legs there in that particular context. Again, procedures level generation, platformer physics-- so a big aspect of this is gravity, which we talked about with Flappy Bird. So Flappy Bird has the bird moving up and down. Really, we're pressing the spacebar or clicking the mouse. And we have a y velocity, which is either going up-- so if the y velocity goes up, character goes down. Everything's based in the top left xy positioning. So positive y is down. Negative y is up. And positive x is to the right and negative x is to the left. The same thing happens here. If we press the spacebar, our character goes up. We get it we give them a really fast negative velocity, but we always have gravity pushing down on Mario-- or quote, unquote, "Mario". So Mario's coming down because that negative velocity is eventually going to turn to a positive velocity and give them a parabolic shape to their jump. We talk about basic AI. We have the-- again, the snail that can move left or right to just very basically track the character. And power-ups-- we talk about that as a concept. We talk about an item that you can pick up. It's not shown in the sprite, but if you jump and hit a block here, you can see something will occasionally come out of the brick, and that will end up giving us points or changing our behavior. And that's really Mario in a nutshell. The assignment ends up being-- make it so that they get to a flag at the end of the level and trigger another randomly generated level. So all the-- and I haven't really talked about this too much-- but all of the lecture exercises-- what they really come down to is just adding a small new piece of functionality to the code base, because if they're game programming-- and let's say, especially if they're entering into a new studio-- it might be possible that they don't have to create this big burgeoning code base. They might just have to make some changes to an existing code base, which is fairly common in industry. [INAUDIBLE] asks, has any universal tool been developed to make it possible for older games to be played at higher resolution, unlike the original, or should they be upgraded for each one? It's not legal, but there are emulators that will come up-rasterize older games, if you have the ROM files for them. Nintendo has rereleased a lot of their games in that same capacity. They'll ship in emulator on a disk, and then that emulator will have a higher resolution version of an older game running on newer hardware, typically. As far as I've seen, that's typically how it happens. There are some ways that you can I think hack older game engines to give them higher resolution assets. And there are even some pretty cool projects related to neural networks that allow-- that take in the art for older games and will actually or up-res them. They'll actually use neural networks to create a much higher resolution version of what it thinks the texture should look like. So something that was written for the Playstation 1 era or the N64 era will look as if it was made for modern computers. It's pretty amazing. Those are usually in the form of mods for games, so I've seen it for-- like Final Fantasy 7 has one of those which, is pretty cool. So good question-- if anybody else has any questions, happy to answer them. Are you using any machine learning in the class? No, we are not using any machine learning in this class-- although, I think Brian's AI class does cover a little bit of machine learning. This class is very light on the AI. The AI in this class revolves around very, very basic heuristics of tracking the player usually, or tracking something besides the player. All right, that was Super Mario Brothers. So folks might recognize Legend of Zelda, or a formula similar to Legend of Zelda here, which was another very famous game of the NES era related to Super Mario Brothers. And this game is a top-down style action-- I guess action adventure would be the best way you would describe it. And we cover a few things here. So now we finally give the player an attack, which creates a hit box in front of them. So we talk about what a hit box is what a hurt box is. We see we have all these different entities, which have all these different textures, and those are all defined in a config file. So we talk about putting data into a file, into a-- it's called data-driven design. So we can you know declare a lot of behavior for things based strictly on just a file-- just a Lua config file. And we didn't get super fancy within this lecture, but if you have a robust enough system, you can actually describe all of your entities in data, and not in logic, and they'll behave in a way that you want. You just have to define all of the different possible behaviors in code, and then the data will pull from those behaviors and create an entity correspondingly. So you can see here, we have top-down perspective-- very ubiquitous in the world of games for RPGs and action adventure titles. We do have a infinite dungeon being generated. So you can see here that the user presses the switch, it opens the doors, they walk through the door, and then it creates another dungeon with random enemies included in there, and a randomly placed switch. That was another big part of this, teaching about triggers. So they step onto that trigger, the switch, and it's connected to all the doors in-- via callback functions that will essentially open them up. And then player can walk through, and it gets reset. And so this is a very important thing in game development, triggers and colliders. Especially in Unity, we talk about that a little bit more, but this is the gist of a lot of like asynchronous stuff. Things that are waiting for the player to interact with them-- they'll be done via the use of triggers, or callbacks. And events is another way that that can work. So you step on the trigger, it triggers an event, and there's a listener for the event. The doors are listening for trigger pressed event, and then they open. The doors open, and then the player can walk through them. And they send a door open event, which then makes them traversable, and so on and so forth. This allows you to do a lot of things that are separate, and waiting, and scattered out throughout the-- your game world, and not necessarily having to pull infinitely frame by frame and do a lot of unnecessary logic. We talk about screen scrolling, which is just a technique-- just a simple thing to allow the user to transition to the dungeon. It's a very iconic thing, but worth talking about-- and again, data-driven design, which is how we define all of the entities shown there on the screen. Any questions about Legend of Zelda? What is the job market scenario for game development? At last I've looked-- I haven't done a ton of research recently, but mobile games are very hot right now, especially in Asia. Asia's got a very burgeoning-- it has had a very burgeoning mobile games industry for a long time, but even in-- at least in the United States-- I'm not too familiar with all regions of the world-- but we have a lot of mobile games now, because people are on their phones more than ever. In Asia, there's a lot more commuting. I've been to Japan, and Japan is huge on the mobile gaming, so you can make a ton of money in Japan. I don't know if it's quite the same situation the United States, but micro transactions, freemium transactions, games that are easy and accessible that you can play on your phone are very big. The indie game scene on desktop has grown a lot, and PS4 made it such that it was easier to develop indie games for consoles, which was a huge thing-- a huge step up from the PS3, which was very hard to program for. And the PS5 I'm not so sure about. I haven't done too much research on it. I can hope that it gives indie developers an easy platform, because indie dev is where a lot of really exciting stuff happens. That's where the Minecrafts of the world end up being created. And then we have AJ sharing a article based on the perspective of a game designer, so maybe you can read that and get some takes from somebody actively working in the industry. It's definitely harder and more competitive than, say, web, because the web is something that-- almost every company needs a website of some form, even if it's just a simple Wix website or whether it's something that's been in being custom architected to serve their business logic. Every company has a website, but not every company needs a game, so you're going to have-- but people love games and will spend money on games, so it can be lucrative. You tend to see a lot of successful indie companies and a lot of successful AAA companies, but there is definitely a place in the middle of that that you might-- you may or may not strike an affordable living, depending on it whether you choose to do it by yourself or whether you choose to work for a studio. If you work for a studio, you're going to be more successful-- more stable, I should say. But if you work it alone, you have a chance, obviously, of making a lot of money and doing something great if you have a fantastic idea, but you might also not get any sales, and it might be rough. So it's a little bit more of an aggressive market. Nitesh asks, through Lua can we generate APK and IPA files for Android, or only EXEs, web, and HTML? If you go to love2d.org, they do have ways for you to generate through the instructions a-- versions for iOS and Android. I have seen that. I don't have a ton of experience doing it myself, but they do appetites and show resources for doing that. So maybe, if AJ has a second, if he can link to that, that'd be super helpful-- appreciate it. And thanks, AJ, for linking all the resources into the chat. That was Legend of Zelda. So let's go ahead and transition. So we go from Legend of Zelda to-- again back to the modern era. So the last two lectures were games that have been around for a long, long time-- game ideas, games genres-- since the '80s. But angry birds came out 2009-ish, 2008-- again, another mobile game. But this game is really interesting because this is a physics-based game. It uses a 2D physics engine integrated with Love2D called Box2D, and Box2D is actually a completely separate engine that you can embed into anything you want, really. But Love2D has its own wrapper for it, so it makes it really convenient and easy to use all of the Box2D primitives-- things like these boxes here and the aliens. You can define them as being collidable. You can define them as being-- as having particular weights, and sizes, and shapes. It's really nice and really easy to get up and running with it. And it's very different than anything else we've talked about. So again, a big philosophy of the course was getting a big sample of the industry, getting-- keeping people excited, keeping the flow going, not spending too much time necessarily on a given concept or idea. And this was a important thing, because there are a lot of games-- and Angry Bridge to this day still uses physics, but there are a lot of games that use physics engines to achieve all sorts of different purposes. So a really small selection of topics for this lecture-- Box2D and mouse input-- so again, using mouse to, in this particular context, drag the ball to create that trajectory. So we're calculating a trajectory based on the velocity of what the ball will be, and putting dots at the different places we predict it will occur. And then just a little bit of simple logic-- if the ball is moving at a particular speed and it hits the box, destroy the box-- and same thing with the box and the other alien. So the aliens are-- we can destroy them and we can destroy the terrain. So you can map all that logic out yourself. And this is a pretty big departure in terms of how things work from the other lectures, but I think pretty important to focus on to work on physics-based games, or game engines. Any questions on Angry Birds-- Angry 50, as we called it, or any of this stuff so far? Do you use some hands-on physics in this course, or just use existing in the frameworks? We use very simple physics with Breakout and very simple physics with Pong and Mario. AABB would be the-- and that's pretty common with 2D games that aren't super physics-focused. We don't cover a lot of super sophisticated physics because typically, in industry, you don't implement that from scratch, because you will just spend a lot of unnecessary time doing it. The math is not trivial, but if you're a fan of physics, and you like it, and you want to do it, the source code for Box2D I'm pretty sure is open-source. You can read through it. You can understand how it works. You can try to implement your own physics, but you'll obviously spend a lot more time doing it than you will implementing your game. And it's going to be a cost benefit for you. If you like the idea of cutting everything from scratch and understanding the internals, then certainly pursue it, but if you're focused on making games and you want to understand how to make products in the market, then you'll want to try to use as many different technologies as possible, put them together into your game, and then ship it that way. You'll save a lot of time that way. Jennifer asks, have you gotten the Lua and Love2D Pong project running [INAUDIBLE]? Trying to troubleshoot myself, but curious if you know if it's possible-- they do have Love2D as an option. I think we tried that at one point. I thought that it was running really slowly, at least based on my recollection. We've tried different ways of doing it. There's an m script in port of 0.10.2 of LOVE that works in the web, but we haven't seen a provider that actually hosts it running, so I'm not sure. We definitely messed around with that a little bit, though. I'm thinking moving to Linux. Which distro would you recommend for someone who is into the CS50 courses? Oh, man, that's a-- that's probably a very subjective thing that a lot of people are going to have opinions on. I use Ubuntu for Windows Subsystem for Linux, but I've probably touched almost every flavor of Linux, and they're all-- I think the differences are only relevant if you're doing really fine-grained stuff or using libraries that were only compiled for a particular distro. Use whichever distro you like, or sample a whole bunch of them. But Ubuntu is what CS50 tends to use, I think. At least historically, that's what we used. We used Fedora for a long time, but we transitioned to Ubuntu. OK, awesome. So that was Box2D and Angry Birds. So the next lecture is something that some folks may recognize, which is Pokemon. So we talk about turn-based combat here, which is, again-- common theme-- very different from a lot of the stuff we've talked about so far. Here we're talking about the idea of two entities taking turns in almost a board game style, and doing some timer-based animations, and having it play out like we're in a battle-- and also having two very different states. We're exploring this overworld state, like a JRPG-- stands for Japanese role playing game-- common genre of game-- where the character's walking around there in the grass-- which is what Pokemon on is, a JRPG-- transitioning into a turn-based combat system here, which shows the character that we're playing as on the left there. And on the right, we have our foe. And then we have health bars at the top and bottom. We have an XP bar at the bottom of our own bar. We can level up and do all sorts of things. And this is really just to show another very common genre of game and how it might work. If somebody were to try to want to make a particular type of game, the goal with this course is to help them know where at least they can look to get a little bit of inspiration or understand how some mechanics might work. Pokemon-- the topics are pretty simple. We cover statestacks. So so far, we look at state machines. Now we're looking at a statestacks-- so being able to actually push a state onto an existing state. So we can pop that state and go back to where we used to be. So if we look back here, you can see where we have this battle that we're doing. We have the option of fight and run in the combat. But as soon as we decide to run, which would be after this turn, I believe-- wait for it to happen-- you can see we-- it fades to white, and then we're back where we were when we trigger the fight in the first place. That's because that state was on the bottom of our statestack. And what we do is we push a battle state on top of that state to allow us to have a much richer game experience. This is common with games. For example, if you have paused menus, or if you have different submenus in your options, or whatnot, you can actually go back to where you used to be-- much in the way that you would click back in the web browser, for example-- and you just have the state of prior positions. And that's a very important idea with game development, statestacks, because just one state machine will just allow you to do transitions back and forth between states, but on allow you to revert back to your prior state. Turn-based system, meaning just the idea of having two entities taking actions against each other and these behaviors happening-- oh, a big, big aspect of this is the idea of GUIs, graphical user interfaces. So you can see we have panels. We have a progress bars in the form of the health of our character and the other character. We have menus, the fight and run. We have the cursor pointing out those. GUIs are ubiquitous in games. You need a graphical user interface for most games. Up until this point, we've only really had press Enter to play, but a GUI is vital. We teach how to implement a very basic GUI, but usually you can find a goofy library or the like. And then RPG mechanics-- the idea of fighting enemies that have health and getting XP, getting levels, getting stronger, so on and so forth-- just to illustrate how that works numerically-- we talk about that. Krista says, seeing these games brings back so many memories. I've had so many kids create these games in VB. I'm assuming that means Visual Basic. Can't wait to tackle this-- awesome. Well, I'm glad you're excited, Krista. Thank you very much. Cool. All right, if anybody has any questions on Pokemon-- happy to answer, because this is where we transition into looking at Unity and the 3D side of the course. AUDIENCE: [INAUDIBLE] COLTON OGDEN: Oh, yes? AUDIENCE: What did you take into consideration when balancing between Lua and C#? And you talk about how Lua is very prominent in the games industry, but I'd like to ask, why did you favor C# over C++ or any other programming language that is very good for game development? COLTON OGDEN: So a couple of reasons-- so balancing things out, the goal was to really provide students with a very fundamental understanding of the coding that goes on in games. And 2D games are a great illustration of how to do this. And that's why we spend the first 2/3 of the course on Lua and on Love2D, just getting very basic ideas-- because a lot of these same ideas actually translate into Unity in 3D. We're just now doing things in three-dimensional Euclidean space, as opposed to two. Excuse me. With regards to C# and C++, C# is the scripting language that Unity uses, and the goal was to give students a ability to program in 3D without having to really bombard them with a ton of-- because if you look at a C++ code base in game development, or if you're looking at-- depending on how far down you want to look-- for example, if you're all the way down at the OpenGL level and you're building everything from scratch, you're looking at thousands of lines of code before you even have anything really interesting on the screen, minus a shape or a textured polygon. And that is a lot to deal with for somebody who just maybe wants to get an understanding at the basic level of the games industry or game programming. Topics like C++, or OpenGL, or like game engine development per se would be better addressed in an a follow-on course, or maybe even a follow-on follow-on course, just given that landscape is so thick to navigate. It can be a lot, especially for somebody that has only taken CS50. So again, this course is kind of a gentler introduction to game development. It's technical, it's rigorous, but it is gentle as compared to if somebody wanted to get into engine development, which is where you would see C++ being used more so, in an engine-- game engine development, as opposed to game development. Modern game development-- for the most part, you're typically not using-- you're not implementing your own engines from scratch unless you set that as an objective for yourself. You're using something like Unity or a framework to jump start your way forward so that you can focus on the things that are interesting. Because you have a game that you want to implement that you maybe want to sell or maybe you want to play or send your friends, you're not always necessarily trying to get a very technical understanding of how things work, unless that's where your brain is. And if your brain's in that spot, then yeah, for sure, then you have-- you always have the option of looking into something like C++ or looking at the source code for a game engine that's open-source and checking it out. But this course is deliberately a little bit less in the vein of engine-- raw engine development, and more game development-- what goes on to making a game, not necessarily how do we implement lighting in a renderer, and materials, and that sort of thing, which would be at the C++ level-- or even the shader level on the graphics card-- good questions, though. All right, so this is the transition to Unity, so from 2D to 3D. We make a big jump. This was a toy project that I made that is similar to the helicopter game that was really famous in the internet days of the 2000s, where you would have a helicopter going through a cave. I certainly played it a lot. And this is a version of that, but we are using 3D, obviously. This is what's considered 2.5D, because we're technically using 3D models, but we are confining things to just two axes of movement. We're not actually using all three axes just yet. So that way, we can test-- or we can teach students simple ideas to begin with, and not jump too much into the Unity stuff. So we obviously teach them the basics of the Unity editor. They know how to get their projects set up in the right way, how to navigate the project view, how to navigate folders, how to create new materials and new models. We talk about C#, which is the scripting language of Unity. Blender is a 3D modeling-- piece of modeling software that we show students, and we have all of the assets in blend files that students can then import if they have the right version of Blender. We talk about components. So Unity is different because, in LOVE, everything is very object-oriented and very standard OOP inheritance type programming-- to a minor degree. We don't go too crazy with object-oriented programming. But Unity is very entity component system focused, which is another paradigm. It's still object-oriented, but the focus is not on inheritance hierarchies. It's not focused on a car is-- a Toyota is a Honda, which is a car, which is an automobile, which is an entity. It's focused on a car has an engine, a steering wheel, foot pedals, a chassis, and a odometer-- those kinds of things. That's what an entity component system is. You have an entity, which is the container for all these different attributes, and that's how entity-- or Unity does all of its logic, how everything is structured. You have a component that does some sort of behavior, you weren't all these components on your game object, and then it behaves the way that you expect it to because it just has all these properties, all these components. So that's what we talk about. We talk about colliders and triggers-- so very easy to do in Unity. Just slap a collider component on something, and you set it to trigger at a certain point. We talk about prefabs-- so pre-fabricated items or objects in the game. So you you set up your thing in the Unity editor just the way you want it, all the right components on it, everything-- all the right settings-- and then you create a prefabs so that you can just drag it back into your scene at any time, and it'll have the exact same attributes-- a nice that Unity does. We talk about texture scrolling again. So you can see here, we have a texture that's infinitely scrolling in the background. It's just looping, very similar to the way we did Flappy Bird. It's kind of, in a way, come full circle, which is semi-deliberate. But you have to do things a little bit differently in Unity to-- or at least we chose to do things in a different way using what are called UV coordinates, which is a 3D texture concept. We talk about that. And then, again, we show how to do audio in Unity, because so far, we had been doing audio and music in Love2D and the way that they do it, and so we show it-- we effectively show how to do this in Unity. And we talk about also how to do different states, different scenes in Unity as well. So a lot of the concepts have translated over to unity at this point, so students have a basic fluency in using the software, but they haven't necessarily tackled a lot of the more 3D-specific ideas just yet. Any questions on the helicopter game lecture or the contents therein. Awesome. So after that, again, big theme-- we do a lot of big changes in GD50 to keep things very interesting. This is Dreadhalls. So this is a horror game. We don't have any gore. We don't have anything super bad, but we have a-- the gist of what it is, which is a maze exploring game-- first person, so we're controlling a character in 3D space. So for the very first time we feel like we're actually in another world in a much more immersive sense than we have been with Mario or Zelda. And we cover a few things, like how to plant a coin objective in the maze. This maze is procedurally generated, so we talk about how to procedurally generate in 3D now. So not only are we procedurally generating things in 2D, but also 3D just to show that the ideas translate across multiple frameworks. These are all fundamental concepts that we can-- we can do these in Unreal. We can do these 2D. We can do these in 3D. We can do these in 4D whenever they come up with a 4D engine. But a few of the concepts that we talk about here are things that are specific to 3D. So texturing-- so having a model and planting a texture onto it, as opposed to just a flat color. In the very first one, you can see the helicopter is just pink. The skyscrapers are different colors. That plane up there's just red. That's just simple flat material shading, but textures involve actual images that we can put onto the models. You can see here, we have brick textures. They're bump mapped, so when they're lit, they actually look like they're jutting out. They're three-dimensional. They're reflecting light in different ways, which is easy to do. We talk about, related to that, materials and lighting-- so using the right lights. So this doesn't look anywhere close to the same lighting as we used in the helicopter game, which is the default light. This is actually dark and dingy, and there's red light coming out of the coin. So this is something we get to do in 3D. You can do this in different ways in 2D as well, but in 3D, we have the ability to really make it feel like we're in a different real place using things that exist in real life, like light and like textures, which is pretty cool. We talk about scenes. We talk about first-person controllers, how to actually-- Unity makes this really easy-- how to actually give a camera the ability to move around using a capsule-shaped little guy that we get to move around-- fog, which is an important thing not only functions as a atmospheric bit of spice, but also can allow you to render more stuff because you can just hide whatever's outside the range of the fog. So that way, you can have larger scenes that maybe have pretty detailed stuff within them by just hiding the things that the fog is obscuring to save you processing power. This was common in the Playstation 1 era and N64 era. It was used all over the place. And we talk about how to do UI as well. It's not shown here, but there's actually a title screen that allows us-- that lets us demonstrate how to use labels and things like that in Unity. Silvana asks, are there practices to write code that will not be out of date with hardware, operating systems, and other kinds of advances in technology? This weekend, we try and play Worms Armageddon, and it was very sad because it hangs all the time, even being a simple game. That's tricky, just because companies can't really project what technology's going to look like in 10, 15, 20 years. That's the unfortunate reality-- or at least it was at the time. Windows has been very good about backwards compatibility, since Windows ME, I believe, which was their operating system, that uses the same kernel that they still use today-- or roughly the same kernel-- so that you can run things just checking different compatibility settings, like they were-- like you're actually running the same operating system. Mac doesn't have that same luxury because they did a major shift in their-- when they went from PowerPC architecture to Intel architecture. The hardcore details of why that doesn't work elude me. I'd have to do my research on it, but I, at one point, knew a little bit more about that stuff. But it can be difficult. Really, it's on operating systems, it's on game companies to really try to think about backwards compatibility. When Sony, for example, releases consoles that allow them to play the older games from older consoles, that's them taking these ideas into consideration using emulators. So emulators are a way to do that effectively, because you essentially are coding a virtual computer that's supposed to be the exact computer that was-- or makes it feel like it's the exact same computer you used to write the software back when the game originally came out. But those are somewhat expensive to run. They can be computationally expensive. And not all companies, not all systems are going to have emulators for them, so they can be kind of tricky, and copyright can make that even more complicated. It's tough. I agree. Thankfully, there are some people that do-- for example, Worms-- I don't have Worms Armageddon was a DOS game. I own it on GOG, but a lot of DOS games just run under DOSBox, which is a DOS emulator. So it's not even a problem. It feels like you're playing it on an old computer. But yeah, your mileage is definitely going to vary, depending on the game, depending on the platform. It's a difficult problem to solve-- good question, though. I will say, the nice thing about Unity is that, because it's very cross-platform and it seems like it's got great backwards compatibility with its older versions and a great import system, it's another plus to writing things in Unity, as opposed to doing it in raw C++ or the like, because then you're not worried about porting your C++ to different consoles, different settings, different platforms later on when operating systems and the like change. So that was Dreadhalls, a very scary game. This is a little bit of a different transition. So this is Portal. So Portal is a game where you're literally-- you have a gun that can shoot portals-- so not bullets, but portals. And you walk through one portal, and you go to the other portal. So you can see the gun within the portal itself they're always rendering what's coming out the other side of them. They're effectively these two cameras that are behind each other-- or behind the portals. They're rendering what's coming out of them and displaying that on the other portal. It's what's called a render to texture. So we're effectively shooting a texture onto a wall that's a rendering the output of a camera. So we have three cameras in the scene right now. We have one camera behind one portal, one camera behind another portal, and a camera that's behind our character. And that's how we get this effect of being able to move-- it's not the most well-implemented version. It doesn't look quite as nice as Portal itself, because there's a lot of other fancy things you have to do, but the idea is the same thing. The gist is the same. The topics that we talk about-- and some of these are exclusive to first-person perspectives, but holding a weapon or an object-- Minecraft is a "first-person shooter," quote, unquote, you're not usually holding-- always holding weapons. You can be holding anything. Just fixing something to your view and moving it with the camera, making it a child of the camera effectively so it always moves the camera moves-- ray casting, meaning looking directly from the center of the camera, shooting a ray figuring out what it collides with, and then doing something with whatever it does collide with-- Unity makes this very easy. Render texture, which is just an idea that's been used all over the place-- but Unity makes it very easy to render the output of a camera onto a texture to give you these cool ways of doing all these interesting effects. Texture masking, which is the ability to take a texture, like this Portal here, and actually define an oval-- so normally, that the camera output would be a square, but we create this mask, this other image that we essentially overlay onto our other image, and it acts as a-- basically, it cancels out the pixels that we don't want based on the algorithm that we use. So that way, we look like we're drawing an oval onto the wall, instead of the square or the rectangle that the camera would output. Decals, which is the texture onto the wall idea; teleporting, which is how we get the ability to jump through this wall and go through the other portal just to teleport-- just player.xyz equals different xyz-- whatever the texture is. And then we talk about a couple of technologies that ship with Unity at the time to create levels, those being ProBuilder and ProGrids, which allow us to make levels in Unity itself-- not necessarily have to delegate to a piece of 3D modeling software. And that's Portal. And that's actually the last lecture of the course, so if anybody has questions about the Portal, I can answer those. If anybody has any questions about the course as a whole-- happy to answer those as well. Where can we find the curriculum for CS50G? I think cs50.harvard.edu/games works. I'm not 100% sure. I'm going to stop showing my screen, because that's actually the end of the slide deck. And let's see if that works-- harvard.edu/games. Yeah, that seems to still work. OK, so I'll post that there in the chat. Let me see. Can you confirm that all software is free to the students and teachers? It is free to the students and teachers. Now, Unity is free up until you start selling your games, and after you make $100,000, I believe, then it becomes royalty. But you're not going to have to worry about that for education. It does seem like folks no longer have any questions, so we can definitely adjourn here. It's been a pleasure teaching you all the curriculum for GD50. Again, if you're teaching in high school and middle school, you will probably likely want to interweave CS50 with games and create a mixture of the two-- and if so, definitely probably the first four or five lectures-- maybe up to Mario, rather than the entire curriculum. If you do have more experience students or you have a curriculum of programming courses, and one of them is the CS50 equivalent, then students can go into this course and probably expect to be able to absorb and learn all the concepts. But certainly feel free to adapt it as needed, and maybe mix and match some of the courses in with this one to get the perfect blend, so to speak.