Learning Pico-8 & Lua, first run
Tags: gamedev, devlog, pico8, lua
Published: 2019-11-13 09:13:08

#What is Pico-8
"PICO-8 is a fantasy console for making, sharing and playing tiny games and other computer programs". Basically is giving yourself a bunch of limitation in quantity of code and memory, because is sincerely fun and fairly easy to pick up.
It's based on a version of Lua and it offers a full suite of creation tools, like a sprite editor and a music creation tool. It's basically an all-in-one system to make games. Also there's a beautiful community based on it, all around the internet, so there's no actual reason not to buy it [here](https://www.lexaloffle.com/pico-8.php)![The starting screen of pico. You can load files or explore other people creations with the "splore" command.](https://thepracticaldev.s3.amazonaws.com/i/lpmtp1h2051rls5dtaaf.png)<figcaption>The starting screen of pico. You can load files or explore other people creations with the "splore" command.</figcaption>

#Starting up
First things first, trying to learn something new is always kinda scary: you don't really know what to do or search for and you try looking at a bunch of tutorials online (some good, some not so much). You follow with the teacher and maybe make something functional, a to-do list, snake or whatnot and then two days pass and you forget whatever you thought you learnt. Been there, done that, and I found out (after reading tutorial about how to learn stuff. Jarring, I know) that a good way to actually learn something is, after watching a couple of tutorials, just to get you on your feet, you need to make something alone, implementing what you learnt and solving actual problems.
![First tutorial](https://thepracticaldev.s3.amazonaws.com/i/6xokid6lncgy3gn9jja2.png)<figcaption>The result of one of the tutorials I followed, I'm bad at this game.</figcaption>
So here we are, I first followed the very nice tutorials on the "game dev with  pico8" fanzine and now I need something to implement.

##### **My university career came in handy, for once**
I'm preparing my last exam, the laboratory part of algorithms and data structures and at the end of the syllabus they talk about pathfinding in graphs and in labyrinths and give some examples of easy labyrinth generation algorithms, so I decided to try to implement those in pico.


# The first run

The first thing I needed to do was adapt the code to generate a labyrinth in Lua and make it work in pico. The basic idea was to use tables (That I didn't understand when I started this, and don't feel comfortable with now. ***My learning plan here is indeed working***)

### Labyrinth generation, basic idea

It's fairly simple: create a set of random direction and, starting from the first room remove the walls in the direction you got. 

It's bad, I know and I will remake it asap. It's like that because it's an adaptation of a recursive algorithm, in which you start in the first room and generate a random direction, then for each direction you remove the wall and call the function on the *adjacent* room, creating a cleaner result. The problem is, pico doesn't seem to like recursion and I didn't want to implement stacks in pico, 'cause I didn't like tables and I'm lazy).
```lua
function make_doors(room)
	local x = (room.x+flr(rectsize/2))
	local y = (room.y+flr(rectsize/2))
	local dirs = {flr(rnd(4)), flr(rnd(4))}
	local id = room.index
	
	for d in all(dirs) do
		if (d == 0) then
			if(id > 12) then
				room.du = 1
				rooms[id-12].dd = 1
			end
		elseif (d == 1) then
			if ((id%12) > 0) then
	 			room.dr = 1
	 			rooms[id+1].dl = 1
	 		end
		elseif (d == 2) then
			if ((id) < 133) then
 				room.dd = 1
 				rooms[id+12].du = 1
	 		end
		elseif (d == 3) then
			if (((id)%12) > 1) then
	 			room.dl = 1
	 			rooms[id-1].dr = 1
	 		end
		end
	end
end
```
<figcaption>My code is cleaner, usually. <b>I promise</b></figcaption>

Obviously, "rooms" is a table, which is not 2D, so I need to advance of 12 rooms to get to the next row ( it's a labyrinth made of 12x12 rooms). So to go to the room under or over the current one I need to move by 12 and checking the mod 12 I can know in which column I'm in (i.e.  if id%12 == 1 I know I'm in the first column because Lua index is 1-based. **It took me like a day to figure that out and my C heritage doesn't like this**)

```lua
function make_rooms(i, offset, rectsize)
	local cy = offset + (flr((i/12)) * rectsize)
	local cx = offset + ((i%12) * rectsize)
	room = {
		x = cx, //coordinate
		y = cy,
		du = 0, //door up
		dd = 0, //door down
		dl = 0, //door left
		dr = 0, //door right
		index = i+1
	}
	add(rooms, room)
end
```
<figcaption>This is how I make rooms. Rectsize is the room size and offset is used to centre the labyrinth in the screen. The index is incremented because I use it for the coordinate generation, but I needed it starting from 0</figcaption>


### The player, the navigation and "light"

In my mind, the game is an extremely basic and kinda crude top-down dungeon crawler thingy and I wanted to give the idea that every room, other than the one you're in, is pitch black and the character is carrying a light of some sort.

To do that, I just thought of drawing only the room the player is in and faking the effect of light illuminating a doorway. 
I initially thought of ray-casting and probably will be the way I'll implement it, in the end, but for now, I wanted something fast and easy to see how it would look in motion (I was stressing out on the labyrinth generator and I needed some wins, **ok?** ***I'm sorry***)

So what I've done is a really bad false ray-casting of light using horizontal and vertical lines

![end result](https://thepracticaldev.s3.amazonaws.com/i/lu5ftdfmqtadefqi6abh.png)
<figcaption>The end result. It's not too bad and it's working at 30 fps. 
<b>I know</b> the player sprite is very nice, <ins>thank you for noticing.</ins></figcaption>

```lua
function draw_rooms(room)
	local x = (room.x+flr(rectsize/2))
	local y = (room.y+flr(rectsize/2))
	rectfill(room.x, room.y, room.x+rectsize, room.y+rectsize, 6)
	if (room.dl == 0) then
		line(room.x,room.y,room.x,room.y+rectsize, 5)
	else
		for i=room.y+1, room.y+rectsize-1 do
			line(room.x, i, room.x-(rectsize/3)+(abs((room.y+(rectsize/2)-i))), i,6) 	
		end
	end
	if (room.du == 0) then	
		line(room.x,room.y,room.x+rectsize,room.y, 5)
	else 
		for i=room.x+1, room.x+rectsize-1 do
			line(i, room.y, i, room.y-(rectsize/3)+(abs((room.x+(rectsize/2)-i))), 6) 	
		end
	end
	if (room.dr == 0) then	
		line(room.x+rectsize,room.y,room.x+rectsize,room.y+rectsize, 5)
	else 
		for i=room.y+1, room.y+rectsize-1 do
			line(room.x+rectsize, i, (room.x+rectsize+1)+(rectsize/3)-(abs((room.y+(rectsize/2)-i))), i,6) 	
		end
	end
	if (room.dd == 0) then	
		line(room.x,room.y+rectsize,room.x+rectsize,room.y+rectsize, 5)
	else 
		for i=room.x+1, room.x+rectsize-1 do
			line(i, room.y+rectsize, i, room.y+rectsize+1+(rectsize/3)-(abs((room.x+(rectsize/2)-i))), 6) 	
		end
	end
end
```
<figcaption>the draw_rooms function. It draws the room and the "light"</figcaption>

# Next up

Ok, what I want to do is:

- Remake(?) the labyrinth generation algorithm
- Faking raycasting again, maybe with lines starting from the character and running in all direction and stopping when they hit a wall
- I need to implement A*, to check if the labyrinth has an actual exit
- Modify the  labyrinth without exit or remove them

# What I've learned

- Fake it 'till you decide to actually make it, I suppose


That's all folks, thanks for reading