Log In  

Press the arrow keys or the dpad to move the map around!

Cart #metatile_tester-0 | 2021-08-03 | Code ▽ | Embed ▽ | No License
22

Have you ever wanted to use larger sprites on Pico-8 and it just got too complicated? Well do I have the tool for you!

Say hello to my MetaTile system, with tools!

While developing a game I created a meta tile system as well as tools I use to facilitate easier development. The tools themselves are very crude, but effective. In the following post I will show you how to use the tools and implement the system in a game of your own!

Download the tool at this link.

This contains a few files that need to be extracted to your Pico-8 carts directory. You can find that on windows by typing %appdata% into your file explorer and finding the Pico-8 folder.

The files contained are:

map_style.css (This is a very very light CSS file that just removes anti aliasing on a number of browsers. The upshot is the images are much sharper and easier to work with)
tile_editor.html (Open this file to start using the tool)
tile_editor.js (Fell free to spool through this file. It's quite janky, I developed the tool in about a day and didn't do much in the way of prettying it up for release. Please excuse the terrible code.)
map_tiles.png (this is a demonstration image that can show you how the tool works)
map_file.txt (this is a JSON file that contains a stored map and tileset. Read on to understand how to load and save with this tool)

A couple of notes before we get started, I made this in JavaScript because I wasn't in the mood to make a dedicated windows application. The upshot here is you should be able to use it across any system. As stated above the actual tool is quite unpolished, but it should still be useful.

Instructions!

This hilariously bad UI hides underneath it a powerful development tool!

First things first, you must go to your Pico-8 project and type the following in the console.

export map_tiles.png

This will create a PNG of your spritesheet titled map_tiles. The tool will only recognize this filename.

Let's go over the window now.

The Selection header shows what tile you have selected at the moment. You can flip this tile vertically or horizontally by checking either the "Vertical Flip" or "Horizontal Flip" box respectively.

To select a tile simply click on the desired tile on the left. You can then place the tile in the tileset by clicking on the window on the right. It will store the correct tile and how it is flipped for use later.

Now we have a couple more useful tools here. We will come back to Make Strings soon, but keep them in mind.

On the Map Editor we have two windows. The left window represents the meta tileset you've created. You can select a tile by clicking on this window. The right window displays what the map will be saved as in the map editor of pico-8. It will look like garbage! This because it is a representation of the hash values of each meta tile. By doing it this way you retain the normal map size, while also getting more fidelity with the meta tile system.

Now let's look at the mapper area.

This is a representation of what the game will look like when rendered using a couple functions in game.

You can place the tile you have selected in the Tile Selector by clicking on the mapper area. The map is delineated into 8x8 chunks that show what a full screen will look like.

Now let's go over the Make Strings button.

By clicking it two strings will be generated that make the whole thing work.

On the left you will see the Tile String box. Select everything in here and paste it into your Pico-8 project. Then store it to a string called tiledat. Like so.

tiledat = "0100020002000200020001103000121024002400210021000400130007000800080008000800071034002800280034100c000d000e000f000a000d000e000b0011001200030003001210111012003000240024002100210013000400170027002a0029002710170038100700071038001c001d001e001f001c001d001e001f001100030003000300030011101400140005000600200020004000400017003800070007103810170038100701071138002c002d002e002f00600060101b001b001100030003000300030011101400140015001600200020004000400017003800070107113810170019002a00290019103c003d003e003f00700070102b002b001100120003000300121011102200230025002600100010005000500017003700280028003710170019002a0029001910690069106900740174016910000000000101020102010201020101112200230026002500100010005000500007010800080008000800071119002a002900191076007610760075007510761000000000440045004500450045004410460046106a006a103a003b004a004a10620062106300631029002a0019002a002900191076007610760075017511761000000000540055005500550055005410560056107a007a103a003b005a005a10720072107300731029002a0039002a002900391076007610790074007400791000000000540055005500550055005410490049004b004b103a003b0009000800080009101300130010001000090008000800091076007610740174016900691000000000640065006500650065006410590059005b005b10660066101a002a0029002a002a002a002a002a0029002a0029001a107900791074007400790079100000000048004810470047101b0023000200020011001110000000000000000000000000000066100000000038100701071138000000000000000000670067100000000058005810570057102b0023000201020111001110000000000000000000000000000000000000000039002a0029003910000000000000000067006710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000670067100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007700771000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

Because of the way pico-8 tokens work this will store the entire tile set while using only 3 tokens!

These are displayed using the spr_ex function I've written below.

function spr_ex(num,x,y)
    sx = num%16
    sy = flr(num/16)
    for i=0,1 do
        for j=0,1 do
            s = ((sx*8 + i * 4) + (sy* 256 + j * 128 ))
            sp = tonum('0x'..sub(tiledat,1 + s, 2 + s))
            hf = sub(tiledat,3+s,3+s) == "1"
            vf = sub(tiledat,4+s,4+s) == "1"
            spr(sp,x+i*8,y+j*8,1,1,hf,vf)
        end
    end
end

The function is structured this way to make it easier to read, but it can be further optimized for tokens. Not many, but remember this if you start running out!

By using this function in leu of the spr() function you can replace sprites with metasprites!

Now the Map String textbox is most important. Follow along carefully.

Right click into the text box and select all. Now copy everything and open your carts folder.

Save the pico-8 project you are working on and open its P8 file in your text editor/IDE of choice.

Under the map header, select everything preceding sfx and delete it. Then paste the copied string into it.

This will completely overwrite your map data so be very careful with this! It cannot be recovered without a backup!

Now, when you load your project and go to the map editor it will look like the representation found in the tool!

Finally let's look at the Save Data, Load Data and Choose File buttons!

By clicking Save Data a txt file called map_file.txt will be generated and saved to your download folder. Because this tool is essentially a web app there is no local file storage and I didn't feel like going through the rigmarole needed to create cloud storage for the files. No worries!

To load the file simply click choose file, select a file that was generated by this tool and then click Load Data. I have included a map_file.txt file for you to test!

If you have further questions please reach out to me here, or at my website!

I hope this tool helps you make very interesting games!!

P#95627 2021-08-03 21:34

Interesting,

I'm not sure I fully understand how the system works. I see that you're using the spr() function, which enables horizontal/vertical flipping of tiles, but are map layouts still stored directly in Pico-8's map memory, or are the metatile "chunks" stored in a string and pieced together using other means to allow larger maps than would otherwise be possible?

P#95637 2021-08-03 23:02
1

So the tiledat string is 256 4 length strings concatenated together.

Each string has 3 parts. The first two characters are a hex number corresponding to which sprite to draw. The 3rd character is 1 if the sprite is horizontally flipped, 0 if it is not. The same goes for the 4th character, only vertical.

The metatile map data is stored on the map with each sprite corresponding to a place in the tiledat string. mget(x,y)*4 gives you the index in the string.

Technically the map can be twice as large, but for my purposes it is the same size with double size sprites!

if we were to comment the actual spr_ex function it would look like this.

function spr_ex(num,x,y)
    //each metatile is 2x2 sprites.
    //convert num to x and y coordinates
    sx = num%16
    sy = flr(num/16)
    //i is the x coordinate in the meta tile.
    for i=0,1 do
        //j is the y coordinate in the meta tile
        for j=0,1 do
            //s is the index in the tiledat string
            s = ((sx*8 + i * 4) + (sy* 256 + j * 128 ))
            //convert the first two characters to a hex number corresponding to the sprite the meta tile is using
            sp = tonum('0x'..sub(tiledat,1 + s, 2 + s))
            //check if sprite is flipped horizontally
            hf = sub(tiledat,3+s,3+s) == "1"
            //check if sprite is flipped vertically
            vf = sub(tiledat,4+s,4+s) == "1"
            spr(sp,x+i*8,y+j*8,1,1,hf,vf)
        end
    end
end

I hope this helps!

P#95638 2021-08-03 23:15 ( Edited 2021-08-03 23:16)
1

Thanks for the info, it's always nice to see someone else's approach to something you're working on. I'll have to do some performance tests on building maps out of sprites vs. using the standard map() function myself, tile flipping for use in level maps seems like it could come in pretty handy!

P#95642 2021-08-04 00:02

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-20 08:48:48 | 0.014s | Q:20