 Ie. Ie. This works closure for game development. So um, this is a bit of a personal passion of mine. I code games for fun. I'm not a professional game developer. I've never published a serious game. This is just a hobby idea in my spare time, but I found closure has been a very interesting language for game development. And I wanted to share a bit about some of the stuff I've been doing, but also some get more into the code and the am y cyfnod o'r ffordd, oherwydd yna y gallu cywrach sy'n cymryd. Felly mae'r ysgrifennu o'r ysgrifennu. Yn ymddur, yw'r amser yn rhan o'r cyfnod yma? Yn ymddur? Rwy'n rhoi'n gwneud yn ymddi'r ysgrifennu, a felly, yw ymddi'r ysgrifennu, mae'r iawn o'r ysgrifennu. Roeddwn i'r ysgrifennu i'r byddwyr i'r ysgrifennu. Mae'r ysgrifennu ymddi'r ysgrifennu. Mae'r personal ffansiwydio, rydyn ni wedi'i gweld i'r codi, ond rydyn ni wedi'i gwybod yn gwahanol i'r game. Le rydyn ni'n gyd i'n gwybod i'r game. Efo'r gweithio, rydyn ni wedi'i gweithio, i'r gweithio ymwylo'r cyfeirio, ac rydyn ni'n gweithio i'r dweud i gweithio, a'r gweithio ymwysigol, i'r 800XL. Mae'r computer yma os yw am 64K ram. mae'n gofyn i ni yn ymwneud i ni'r rhaid i ni i ni. Rwy'n edrych. Mae angen i ni'n dechrau i ni'n gwybod i'r code o JPEG. Mae rhaid i ni i ni i ni'n gwybod i ni'r code o JPEG. Mae 1.77 MHz, CPU, mae'n gwneud i'r GHz a MHz, i ni'n 8 bit registers. Mae angen i ni'n 64 bit non-sens. Mae'n credu 1 character i'r register. Mae angen i ni'n gwybod i ni'n gwneud i ni'n 127. You had to use two registers, sorry. A modern PC is about 100,000 times more CPU power based on MIPS instructions per second, about 400,000 times more RAM. That's a kind of idea. But I loved it, and you could make games of this. One of the great things about game programming is it really does teach you some different ways of programming, how to program efficiently, how to make sure there's good performance, y gallwn am y cyfnodd, y gwirionedd, y gallwn bod yn cymryd? Y gallwn yn tynnu'n gwybod? Y gallwn yn gweithio? Dwi'n ffawr, lle mae'r ddataethau a'r ysgolfau ar gyfer y gweithio yn y gweithio'r ysgolfau? Mae'n fwy o'n gweithio dda fi'n gallu ei gwirionedd yn cymryd mewn amser cymryd yn y ffordd cyffredinol ac mae'r ysgolfau ar gyfer y gweithio'r arwad yn ei gweithio. Zael, mae'r gynllun o'r wneud y Fetaerie XL i chi arferrwyddwyd a'r gynllun sy'n gwneud hefyd. Wrth gwrs mae'r gweinhwc gwneud y sylwbbook wedi'i rhoi ffawr 160 x 200 o elais byddwyd y lluniau yn gorffent. Mae'r gweinhwc gwneud yn rhaniaid. The only thing to do is to focus on that at a time. But you could have to think about it. Because the process was going so slowly, you could trick it. You could change registers while it was drawing the screen. It would change the colour of things. That's how they managed to make this line in different colours from these lines. You just do all these stupid tricks to try and make anything work at all. So, what do you need to make a game and sort of bring it back a bit more to the sort of closure context? A game is actually essentially very simple. First, you have to set up the game. What's going to run? What does it look like? What's the environment you want to run? You need to get some input in the game. What's the user doing? What are they trying to do? Are they moving? Are they not moving? Are they entering a command? You then need to update, but based on the input, that's going to change the state of the game. Once the state of the game has changed, you need to report the results back to the user output display the game. You just loop. Games basically have this main loop where you go round and round and round and round. What's quite interesting about this is you can see all of these as basically state transition functions that operate in the context of the game. So, you're starting off with some configuration. That might be the game options or the environment or some parameters in the game. You've got some function that creates the initial state of the universe, the game world, if you like. That could be a pure function. Quite often it is not a pure function. Anyone can guess why? Persistence? Persistence? It could be. Persistence is one reason. Environment. You could read something from the environment. Although, if the environment could still be a pure function from the environment to the state. Video buffer. Could be some weirdness in the setup. Usually I've found it's randomness, in fact. Quite often, when you're in games, you often... Some of you came to my talk on closure graphics before in generative graphics. I talked about how you can use random number generators to create these images and fractals and this kind of thing. You might want to use those in your game setup function when you're generating the world. In fact, the game I'm going to demonstrate actually has a bit of that. But it could be a pure function, but maybe you decide you want to put some randomness in or something like that to make it a bit more interesting. Input then... This is a function that just reads from the world. So it's an impure function because you're getting external input. But you're getting some kind of an event. The event here could be a key press or a mouse button press or someone moves a joystick to the left or to the right, any of these kind of things. But then there's sort of the core of the game and I think the most interesting function of all is when you take the state of the game, the current state of the game, plus an event, what just happened, and you transition that to the next state in the game. That can be a pure function. So you've basically got an immutable state of the world. You run it through a pure function with whatever the event is and you get a new state of the world. That's actually quite nice from a functional programming perspective. We can actually reason about this. You can also imagine the entire running of the game. It's like reducing over a whole bunch of events and then creating a chain of different states of the world. And then output is basically you take that state that came from the update function and you get some side effects. So typically those side effects are drawing the screen. So you've got some internal data structure which represents the state of the world. You run it through then a rendering function and the rendering function paints the screen. Now in most games, you actually throw away the whole screen and repaint it every single frame. So it paints one frame, it creates a buffer in the background, it paints a new frame. Once that frame is finished, it throws away the first frame, displays that one and so on. It just creates new frames continuously. Some games do try and retain the old screen and just update the regions that they need to. It's more complicated and it turns out it's actually harder to do it that way on modern graphics cards. You might as well just redraw the whole frame in one go. You might also have other side effects like sound. If you want to kick off any sound effects or maybe you've got some flashing lights around, whatever. So that's basically the core concept of a game loop. This loop is running in an action game. You'll be running it probably at the same speed as your screen refresh. Or you could run it like once every two screen refreshes if you want to. But you've got it running on a sort of fast iterative schedule. You could also in some games like a turn-based game will run on a slower schedule. In fact, they'll actually probably only run this loop when actually something happens, when actually an event occurs. I'm going to talk about this in the context of a little game I made. It's called Alchemy and it's a closure roguelite game. Now Rogue, anyone heard of the game Rogue? No? Oh, that's sad, that's sad. I don't blame you because I'm an oldie. Rogue was a classic game. It came on some of the very old early PCs, the very early IBM PCs. It was basically one of the first games that actually had exploration of a lost dungeon and finding secret treasure, this kind of concept. You didn't actually have any graphics then. You just had character terminals, like a shell, effectively. You had no graphics and they wanted to play it on these terminal emulators. So the idea of the game was when it's all rendered in ASCII. I think it was one of the first games that ever used an ASCII colour terminal. Your hero is like an at sign, an S is for snake. These are like coloured cells, which are walls. Those little things are some kind of food. But it's basically an entirely ASCII-based game, but it's still interactive and it's fun. This is spawned a whole community of people who just like making roguelite games because they're quite fun, they're quite interesting to build. They've got a lot of actually interesting game development things, but they're not too hard. So this one was for a seven-day roguelite competition. You've got one week to write a roguelite game. I think I spent about three or four days on it during that week, so it's a fairly small game project. But the typical features say of ASCII graphics, basically in these kind of games, using fancy graphics, is just found upon your cheating. None of that. One of the things that is very interesting, they have a lot of random dungeon generation. So these games are typically very replayable because every time you play, it's completely different. Different maps, sometimes different monsters, sometimes different items. You don't really know what you're going to get. So part of the fun of the game is exploring a completely new world every time. They have monsters, obviously, to kill. They have items, so you can pick up items in the dungeon to make your quest easier. It's turn-based, so it's more around tactics and thinking about how you want to play the game, rather than speed or reactions. The game basically pauses until you make a move and then everything happens and then you get to pause and make another move. And there's this concept of permadeath. You just die and you start again. So it's a hardcore game in that sense. Okay, so that's the quick intro. I'm glad to get out of PowerPoint. We can actually do some closure. So this is the alchemy project. By the way, it's all on GitHub. If anyone wants to download and play with this afterwards. I'm just going to kick this off. I'll show you a trick, by the way. I often do when I'm doing these kind of projects. I often have a Java class, in this case gamap.java. It has a sync just one main function, and all it does is closure.require and closure.val in order to launch the closure main function. But that means you can package it as a Java app without any fanciness. Yeah, just a standard main class. Which means you don't need to AOT anything or anything like that. So it's a nice trick, depending on how you want to bundle and package your game. Anyway, I'm going to launch it the closure way in the REPL. I always code my game experiments like this. I start building them at the REPL and then figure out another way to launch them if I need to. And I'm going to launch it. Hopefully that's going to work. Okay, so this is the game. Welcome to the dungeon Alchemist. Seek the Philosopher's Stone. I'm a little at sign. I can wander around the map. So I'm just using arrow keys here. It's got a few nice features. It's got a line of sight calculations. So you can sort of see as the dungeon gets revealed as you walk around it. You can see that the dungeon has got these random features that look a bit like rock corridors and some rooms. What's that? No idea what that is. I feel refreshed by the healing waters. The fountain dries up. Okay, so I'm an idiot. I've just potentially lost a major advantage. I had a healing fountain. I wasn't even injured. I drunk all the healing water. I'm probably not going to survive. I'm a stupid adventurer. But I've got another healing fountain. Okay, so part of the fun of the role-like game is you figure out what's going on in the world and you work out how to take advantage. I'm not going to drink that one. I've learnt my lesson. So you wander around the game. Oh, it's a goblin. So this guy basically has got some simple AI. He runs after me. He chases me. He tries to beat me up. If I'm lucky, I escape him. He's going at the same speed as me. So he's... Okay, I'm not going to run away from him. But if I run myself against the wall, if I press dot just to stay still, I wait, the small goblin... He's trying to hack me, but he's a bit clumsy. He's not going to do anything. I say, okay, I'm a bit bored of this. I'm going to bash him. The small goblin blocks my attack. I hit the small goblin for two damage. He hits me, but causes no damage. Miss the small goblin. Oh, this could take ages. Okay, I've killed him. And there's a fairgrass weed here of some description. So I picked that up. I take the fairgrass weed. Let's see what I've got in my inventory. There we are. I've got three magic mushrooms, some craft boot potions, fairgrass weed, healing potion. Okay, so the game's about alchemy. So it's all about collecting potions and mixing potions. And you're using them to outwit the enemies and stuff like that. That cure poison potion may come in useful, so I'm not just going to drink that for fun. But you get the idea of the game. There's ten levels in the game. There is, in fact, an objective. You can actually play it and you can actually win it with a bit of luck and a bit of figuring out how the game works. The sort of tradition in road-like games is that the top level is super easy, but then it gets harder as you go down. So there's some quite dangerous monsters if you go a little bit deeper. Okay, so that's the game. Any sort of questions about the game and the sort of concept of the game? Super question. Actually, this is... Let's go and look at the code. Redraw screen. Okay, so... I'm doing things a bit out of order, but this is the redrawing for the main screen function. It takes the state of the game. You can think of state as the sort of entire... In this context, it means the entire environment, so it's got information about the frame and the sort of configuration of the screen. It's going to redraw the world, which is basically this part. It's going to redraw the messages, like if something just happened in the game, it sends those little messages to say what happened, and it's going to redraw the stats, which are basically the stats about your character around here at the bottom. So basically it's taking that state and it's having three side effects drawing different parts of the screen. If I go into redraw world... Okay, good example. So it's going to... This is something that's quite common. The entry point is actually here with a state as an input, but in fact there's another bit of input that I want, another parameter I want, so I'm basically extracting that. In this case, that's the location of the hero, because it's actually quite important where the hero is basically determines where you draw the screen. The reason it's done this way is because if I wanted to show the screen at a different location, you can use the second... the second arrow tree of the function to draw somewhere else, but normally you just want to centre on the hero, so it's natural that you just extract the hero's location. Notice this piece here, there's actually the state that contains a field called game, and it's actually an atom, so I'm just pulling out the current version from that atom, and this game is actually immutable. So the entire actual definition of the game world is a single immutable data structure. The state, as the thing called state, has a couple of mutable things inside it, including the definition of the game world which changes at each game step. So that's just what we're doing there to pull that out. So we're pulling up a bit of information about... we're pulling out the game, we're pulling out the hero, because that's going to affect the rendering and a few different options. We've then got three things that we want to pull out. One is an object called visibility. That's basically what is visible on the map. We need to know which squares we can see or not see. We need the location of the hero again. If there's no location, we use the location of the hero. If there's a location, we keep the location we've been provided. And we also need to know what's been discovered so far. So if you see on this map, the bit that's highlighted is basically the bit that's currently visible. The bit which is greyed out has been discovered before, because I've walked around there, but it's not visible currently. So we need to know the difference between those two different areas. We then figure out some Xs and Ys, so the area that needs to be painted. And then we just loop over that area. I won't go into all of the maths, but basically you're just working out what the rectangle of the screen is, so there's an X and a Y loop. And for each location, we're saying, okay, is it visible? And we're working out what the tile is. Is there a wall? Is there anything like that? If it's displayable, or there's something that you can see, then effectively you're drawing it. And we actually, with a bit of Java interop, I'm actually using a Java class which emulates a console, so this sort of ASCII console. What I'm doing is I'm working out a foreground colour, a background colour, and this T is in fact the name of a character, what character I'm going to draw in ASCII. So I'm setting a background. JC is the J console, which is like a terminal emulator. I'm setting a foreground, I'm setting a background, and then I'm just drawing a single character at that location. And I'm basically looping over, drawing each of the characters across the whole thing. Make sense? So this is basically part of the rendering loop for the game. If I redraw messages, is doing something similar? It's also looking at the content of the game, which is the current date of the game within the state, is getting the messages from that, seeing how many messages it's got, and then it's filling an area, setting foreground and background, and just drawing for each of the messages that it wants to display. There's a feature, I can press M and see like all the messages, it's got a message log, so you can go back if you're interested, or if you've missed something. Answer the question? So it's basically the entire thing is a function from the current state of the game to side effects, which are basically painting on this console. So you're using the console effect as a canvas. Do you have any fancy function to draw boxes? All are single? Yeah, there's a fill area. So this one here. So this is filling the area of the console with, that's a character, so that's space, text color, and black background. So if I fill with spaces and a black background, I'm basically blanking it out. So I'll see if I get a message if I run into a wall. So what it's doing is it's basically drawing a big black square before drawing the message on top of it. So there's a couple of utility functions like that which just make some of these things more convenient. Yeah. Okay. How much of the game world is pre-defined in how much it's generated? Is it just the maps or the different monsters and stuff in the rules? Great question. Yes. There is randomness throughout the whole thing. The main randomness is in the map generation, a couple of things I wanted to... So this one's... One of the things I did here which I think worked quite well was I factored the generation of the library because basically every game has like an asset library. Yeah. What are the different objects that exist in the game? What are the different monsters? Et cetera, et cetera. And I basically factored the entire generation of the library into a function at the beginning of the game. Yeah. Which is I think an interesting... interesting approach. Let me just see if I can find the entry point on the second setup. Yeah. Okay. This is it. So this setup is going to basically build an object library, all of the different monsters, all the different items that can possibly exist in the game. Yeah. And what we're actually going to do is we're actually going to sock that into the game itself. So the library of all possible things that can exist in the universe is stored in the universe. It kind of makes sense. Yeah. And we run this function buildlib. Now buildlib is basically going to create a big map of all the... of all the different possible objects which exist in the world. And it's a map of names to properties. And... Who's used this as our thing? You've used this? Yeah? This is super cool. Yeah? This is the single most useful function when doing this game coding I've found. It's like the best macro. What it does... I'll just do a quick demo. What it does is it lets you give a value to a symbol. Let's do one, two, three. And let's call that A. Yeah? Now normally when you're coding code and you define a symbol, you'd have to, like, redefine A, and then B is A plus something else, and C is B plus something else, and you have to, like, build a whole bunch of steps, and you have to keep introducing new intermediate variable names. Yeah? That's kind of annoying when in these game environments where you've got this game, which is the state of the universe, every single step you're going to have to pass the game to it and you're going to get a new game back. Yeah? So you're always going to have this pattern of updating the game, getting a new game back, updating that game, getting a new game back. What this... Okay, let's... Let's imagine this is the game, yeah? So let's... The game world is a list of one, two, three. I can, you know, conge game... Oops. I can do conge game four. And I get one... Oops. I get one, two, three, four, yeah? But typically I'm going to want to do more than one thing in a row, yeah? So I can do conge game ten. And now I get one, two, three, four, ten, yeah? So game, it gets redefined each line, yeah? The first time I'm adding a four and the next time I'm adding a ten, yeah? Yeah. So... So basically you can build up successive transformations using this pattern. And that's what I'm doing here in the build lib, yeah? I'm defining the lib to be just this map to start with with an empty array of objects. Then I'm going to define all the objects in the lib. And then I'm doing a couple of post-processing steps which we don't need to particularly worry about. Define objects, I believe, uses the same pattern. Yeah, so then it's going to pass the lib. I didn't use the as thing here, I just used the standard arrow. But define the base, define the tiles, define the effects, define items, define creatures, define hero. So each time it's basically putting the lib into threading it through these operations. Let's do... Let's look at one of these, let's look at define items. Define base item. My God, there's so many of these things. Yeah, okay. So what I'm doing is I've got, again, threading through the lib. I have this function called proclaim, yeah? Cos it sounded good and a bit archaic for this kind of game. And what that does is it's saying, well, I want a base item to be all the properties of a base thing plus whatever else I specify. So it's almost like prototype-based inheritance. You're basically adding new things to a map. So a base thing has some properties, but I want to add is item true. I want the default character to be a percent sign. So if I draw on on the map and it's a percent sign, either I meant it to be like that or I've forgotten to change the character. I've got can stack. So can it does this thing stack with other items of the same type? Can I get 10 of the same thing or will they be separate items? And I have a z-order. So z-order is like which things display on top. If there's many things stacked on the same square, which thing do you want to draw on top? Some items on the ground. So otherwise those sneaky goblins can hide under the rusty coin on the floor and it wouldn't be quite right. But then the other items are then based on that. Yeah? Scale down. So once I've got, because it's threading through, each of these proclaims is adding to the map. So by the time I've got down to this point, base item already exists and I'm creating a base potion, which is built on top of base item. So this has some extra properties. Its potion is true. You know the recipe. The character is a little exclamation mark. Let me drop one of my potions. Yeah, the exclamation mark. That's a potion on the ground. If I stand over it, there's a healing potion here. And then what I do is I have some properties in the maps which are actually functions. So I have an on-consume. What happens when you consume a base potion? It doesn't actually do much. It just says the potion tastes horrible. But these are the functions that actually get invoked when you carry out an action with the item. So what I'm actually doing is I'm building up the code inside the library object, which is a data structure which describes how all the different items work in the game. And then the game will end up referring to these and it can actually execute these scripts. This is, I find, a much better way of coding games is to actually put your logic in the thing that you're designing. Here I'm designing how a potion behaves. So I want both the properties and the logic related to the potion in the same place. Otherwise it would get scattered across the code. And there's quite a lot of items in a typical game. This is quite small in some senses. And you can see that there's all different kinds of items. One of the things it does do is it randomises the colours of the potions. So there's a bunch of different potion colours and it assigns random potion colours. So the idea is that you don't necessarily know what a blue potion is until you've tasted it. So you either need to take a risk and drink the potion and discover what it is, or you find out some other way of identifying it. So that's part of the strategy of the game is do you risk drinking a potion because it might be useful or do you want to try and save it or try and identify it later, et cetera. So that's an example where the randomness actually gets inserted in the generation of the items, which I think was the original question. But I just wanted to give context of how this works. So that randomness basically alters the library and then the rest of the game will run with a blue potion being a healing potion. But the next time a red potion could be a healing potion. So as a player you can't learn the potion colours to give yourself an advantage in the next game because it's going to be different. You can have a walkthroughs online. Exactly. No walkthroughs for this game is guaranteed to be different every time. And there's a bunch of other things around that. What's quite interesting is I found a way to make the actual definitions of potions really, really small. And I was quite pleased with this. So I think this is about as simple a definition as you could get. So a regeneration potion, it descends from a base potion, so I'm defining the inheritance. I'm saying what level is, I think the level is when it starts to appear. Does it start to appear at a random level between 1 and 8 or something like that, so where you find it in the dungeon. And the only other thing I specify is what happens on consume. And the only thing that you need to specify for on consume is it's a potion effect function, which means a potion will add an effect to the character and the effect is called regenerating. And that is all you need to create a complete potion in this game. And if I copied those three lines and I pasted those three lines and changed it to a foobar potion, you would get a foobar potion in the game. And it would get generated at level random 1 to 8 or whatever it is. And the effects themselves are defined. So the effects are objects in their own right. Define. Base effects. Yeah, so there's like periodic effects. So if you're healing, for example, you can regenerate some life over time as you walk around the map. Poison will take away life over time as you walk around the map. And that's all specified in this library. So a lot of the complexity basically gets put in the definitions of the objects in the game. How am I doing for time? Cool. Okay, so that's the library, the library generation piece. There's also a dungeon generation piece. This is actually what creates the world. Yeah, I think this is the entry point. And it's using my own version of the AS macro, which basically does exactly the same thing. But if Neil gets returned, it bails out. Yeah, so it's like an and. Yeah, as long as it keeps returning something which is truthy, it'll keep going. But if Neil ever happens, it stops. Now that's useful because sometimes random dungeon generation can fail. Yeah, like imagine the situation where you've come how created a whole bunch of block squares and you can't place the finishing point at any point that the hero can ever get to. It's basically failed to create a successful dungeon. So you have to bail out and try again. It's very rare, but it does happen. So this and as macro basically means you can bail out by returning nearly if you go, hey, I couldn't find a route through the dungeon. So that means that the dungeon is always guaranteed to be completable. It also is a bit more efficient if there's potential for failure. But yeah, it's basically creating a game. It's defining the volume. It starts off actually filling the entire space. It's a 3D space. It fills it with a rock wall. And then it actually starts hollowing things out to actually create the different different caves and items. So it generates the region which is the entire region to start with. It places an exit staircase which you need to finish the game. And it places the philosopher's stone which you need to reach to win the game. So basically you have to go down to the 10th level, find the philosopher's stone, get back up to the first level, and then escape out the exit staircase. So those are only two things. In fact, they absolutely have to exist in the game and have to be connected. It decorates the rooms. So rooms get generated in earlier stages but they don't have anything in them. What it does at this step is it then adds features and things to rooms like fountains or pillars or pools or this kind of thing just to give the game a bit more scenery. And then it does connect levels which is basically adding staircases between the levels so that you can go between them. I do that twice because I want enough staircases that you're not searching around for the only one and only way of going up and down. It gets a bit boring if you have to go... So just to make the game a bit more dynamic. But I could have done that a random number of times or I could have had some different probabilities in there. But you want the game to have enough connectivity that you can actually explore the map. Generate region. So it's a 3D space. It basically loops over the Z levels and generates each level one by one because each level's potentially got some slight different features. So it calls generate level. It's doing reduce, actually. So what it's doing is it's just reducing over the range of the levels, the Z levels of each dungeon level. And each iteration of the reduce is simply generating the next floor so that the game gets updated on the next floor each time it runs through. Generate level is... There's something around... There's something around creating an underground stream sometimes optionally, but generally it's doing these generate zones. And a generate zone is... What it's actually doing is quite interesting. It's recursively splitting. It's a split direction. It's recursively splitting the level into sub areas. So you sort of get like this sort of fractal layout of rooms or areas, zones in the level. Let's see if we can see that in the map. Yeah, so you can probably see it a little bit here. Yeah, so you can see this long wall here. This was probably a zone split between this part of the dungeon and this part of the dungeon. So what it does is it subdivides the dungeon into different areas, these level into different areas as it generates it. And that basically labors you to break down the problem into defining smaller areas. And then once it gets to the lowest level, it decides, okay, randomly, is this going to be a room or is it going to be like a rocky area with a tunnel inside or is it going to be a room with a pool inside or is it going to be like a rocky area a room with a pool inside, et cetera, et cetera. And that basically enables it to generate this sort of variety in map layouts. There's a bunch of different techniques you can use to generate levels, but that's one I found that was quite fun to play with and quite efficient for this kind of game. But again, there's a randomness in here. So the world generation is not entirely a pure function. It's doing some random splits of the map. I think I'm probably running out of time. Are there any more questions on stuff that... There's so many objects in your game. How did you come up with it? Did you plan everything up front or did you go along as you went along to just modify it? In terms of the objects in the library? The many maps that you have. These maps? The maps. Yeah, so... I started with some ideas around what are common properties I knew I was going to have. So one of the things I knew that is blocking is it something which will block the movement of the hero. Like a wall blocks the hero, but a bit of grass on the ground doesn't. So there's some properties I knew that I was likely to need which helped me decide what the map keys were going to be. But then a lot of this I actually added as I was experimenting with the game. So my thought process was, well, some of these rooms are a bit boring. What should I put in a room? What might you find in a sort of hidden underground room? I don't know, a torchwrak. I'll make a torchwrak. So I found an ASCII character that looks suitably evil and torchwrak-like. Let me find it. There you are. So it's a torchwrak. It descends from base decoration. It has char 0x4C1 and the foreground colour is... C-O-C-O-C-O is a yellow. No, a white, a light grey. Yeah. So that's a torchwrak. So that was... And then I think somewhere in the dungeon generation I specified some kinds of rooms would get a torchwrak in or something like that. But that's enough to create a new item in the game. So one of the great things about closure was it made it really... And playing in the weapon, I didn't have to reboot the game. I could do this pretty much with two weapon commands and test it out. One of the things that was so great about closure is it made it so easy to play with adding things to the game like this as you go through. To me, that's part of the fun of game development. You don't have to plan the whole thing out as long as you start with a good framework and a good conceptual idea of the game. You can add so much of this stuff as you go along. And that was fun. This was the fun part of the game, was just going through and saying, what if I want a rat? Let's make a giant rat. Can have a dragon. This is what's fun. If you can get things in a way and sort of... It's the case, I think, of moulding the language to support my way of thinking. My way of thinking was very much I want to experiment. I want to be able to define new game objects very easily. So I want to basically create a DSL almost, which is going to enable efficient definition of game objects. I think that worked quite well in this game. Have you tried to use other language to create something? Yeah, I've written games in a few languages. A long time ago, I used to write in Delphi, Pascal, Togo, Pascal. I've done some C++ basic. I've originally learnt coding in basic. I've done some games in Java. Yeah, a mix of things. The closures, I think, has been the most fun. I've written some more sophisticated things as well, like some OpenGL stuff and this kind of thing, which is... This is actually fun because it shows more of the language, whereas talking about OpenGL is more about maths and pixel shaders, which are less of a closure thing. This is actually a nice example of using closure. I've tried a few different languages. Closure is pretty much my favourite of all the languages I've used for gaming. It's a good language, a mutable data structure is actually surprisingly good for gaming. If I have time, I'll show you one little trick. So remember this position, okay? I'm just going to run this. I'm basically getting the current state of the game. I'm just going to store that in a var. So original G is basically the current state of the game. I am going to run around somewhere else. I'm going to drink my fountain. There you are. The fountain is empty. What I'm going to do now is I'm going to reset the game in the atom to the original game. So it's a persistent data structure. It should have the old version of the data here. Well, that's because I forgot to redraw the screen. I've changed the data structure in memory, but I haven't actually changed it on screen. I'm back and I go down and my fountain is refreshed. So you've got this time travel ability. There's actually somewhere that you can find a time travel potion that basically memorises the point at which you drink it and calliports bactrid at some other point. There's some random stuff like that, some little Easter eggs hidden in there. But that kind of stuff is great for just an experimental design. Anyway, I think I've probably used up all my time, but hopefully that was interesting. If you want to play with the code, it's all up on GitHub, so have a hack.