Pxt-TilemapGen: an extension for messing with tilemap data!

After messing with other peoples’ extensions, it’s high time I made my own! I’ve always had fun messing with the underlying data structure of tilemaps, so now block users can too!! Now, don’t get me wrong, this is not a perfect extension, but I can use it to do all the stuff that I want to do, so hopefully you can too!

WoofWoofCodes/Pxt-TilemapGen

Demo!!

It’s mainly called tilemapGen because by using it, you can create tilemaps of any size you want in runtime, using an array of numbers to specify which tile goes where. This could be used for things like saving tilemaps and generating them using algorithms for random worlds and stuff. I’m just going to go down the list of blocks, because I can’t really decide where else to start. Also, let it be known that I didn’t really organize the blocks very much, so they are kinda all over the place :upside_down_face:

Blocks:

Get normal tilemap ( ) tilelist

Allows you to grab the list of blocks used in a normal tilemap, in the form of an array of images. As @richard explained here, it is not possible to just grab a list of all the tiles that have been defined, but it is most certainly possible to steal that list from a tilemap that uses them! So yeah, that’s the purpose of this block. It is important to note that the tilemap must be using all the tiles you want to grab, so you can’t just use a blank tilemap, unless you just want transparency16, which is a 16 x 16 blank image.

(tilelist)

This stores a list of tiles for you. This is just the little block that lets you Get that list. Nothing special.

set tilelist to image array ( )

You put an array of images in there and you can access it with the little “(tilelist)” block above. This array is also used by other blocks later. It is important to note that this does not add to the array, it overwrites it. Keep that in mind.

add tile (image) to tilelist

Self explanatory.

add tilemap with id ( ) width ( ) height ( ) data array ( array of [] ) wall image (image)

Now we’re getting somewhere! I made a sorta kinda maybe convenient(?) way to store tilemaps that you make using an ID system. If you make multiple with the same ID, the one found when you search (block that comes later) will be the one created first. The width and height fields are obvious. The data array is what you use to hold the locations of each tile. For example, if I made the first number of this array 0, the top left corner of my tilemap would be whatever tile is in the first (0) index of the tilelist array. Usually, in a built in tilemap, this would always be the transparency16 tile, but you can do whatever you want! If you make the data array too short to cover every tile, the rest will be filled in with 0s for you. The list defines tiles going left to right, top to bottom.
The wall image is another thing! Drawing red in this image will make walls on the corresponding tiles. (That’s color #2 for all the color palette changers out there) You should probably make this image the same size as your tilemap, but who am I to judge? Do whatever you want lol.

< map with id ( ) exists >

Self explanatory. It’s a Boolean, so it’s either true or false. You put them in If statements or whatever, idk.

( map with id ( ) )

This is how you access your stored, id having tilemaps! Now, you can’t just put this into a “set tilemap to ( tilemap )” block just yet, you will have to use the “( (tilegenMap) [tilemap] )” block to do that. It’s down below in the Saved Maps section. Just replace the “(tilegenMap)” variable with the “( map with id ( ) )” bit!

generate tilemap with (tilelist) width ( ) height… etc

Now this one you can put into a “set tilemap to ()” block! These tilemaps aren’t saved, unless you save the data yourself of course! If you want to, you can take out that little “(tilelist)” variable bit and put in whatever image array you want! Have fun!

Saved Maps section:
(“TilemapGen” shortened to “tmg”, and I will only be covering the Set half of the Get/Set blocks because the Gets are pretty much self explanatory)

set (tmg) wall image to (image)

I would say this one’s self explanatory enough.

set (tgm) tilemap to ( )

I honestly don’t know why you would use this one, because the other variables don’t change when you use it, so everything ends up all wrong and stuff. This element just saves a pre-packaged version of all the tilemap data so that it doesn’t have to re-compile it all every time you use it to set the tilemap.
The Get part, on the other hand, you really need that. It’s how you put the “map with id ( )” block into the “set tilemap to ()” block, so it’s very important.

set (tgm) map data array to (number array)

You use this to change that. Yup. That’s it.

set (tgm) width/height/id ()

The first two, width and height, are obvious. Fair warning though, messing with these will mess with all sorts of squishy wishy stuff with your tilemap, especially messing with the width, which would lead to your blocks and everything sliding all around. This also does not change the wall image at all. Also, you’ll probably get very confused if you start changing around IDs, so unless you know what you’re up to, maybe don’t touch any of these.

Yay! That’s all the blocks! If I missed one, it’s because I added it after this was posted, so check the replies to find an explanation.

Hope you all enjoy!!

12 Likes

If you want to use this extension with 8x8 tilemaps (the tile-util small tilemaps), you can now do that in written code using

tilegen.tileScale = TileScale.Eight

I might add this to block code in the future, but probably not cause I’m lazy and dropdown menus are annoying to code in block definitions.

(Deleted and edited cause it’s not tileSize it’s tileScale)

ah yes, what a wonderful creation! I can see it now, an influx of forms of survival games based off the fact they used this system sense they can’t figure out anything but blocks (so basically me). great job!

1 Like

I already have something like this planned :rofl:
Goodluck to everyone who’s trying make one!! Also, a small gift, there’s a video called “Programming Perlin-like Noise (C++)” by javidx9 that was very helpful for… terrain generation reasons… :wink:

1 Like

hey, wait, does this mention you might be able to save tilemaps with this??

1 Like

It’s… complicated…? The thing is, as far as I can tell, there isn’t a way to get the tilemap data from a normal tilemap (a tilemap that you make in the tilemap editor), at least not in run-time (if you switch to a language other than blocks, you can look inside the tilemap.g.ts file and see all the tilemap data and copy it). On the other hand, it is completely possible to have a tilemap data list, save it with the settings extension, and then create a Tilemap from the saved data when you run the game again.
So, technically, it has always been possible to save tilemaps, as you could have saved a list and then used that list to place tiles on an empty tilemap…

1 Like

hey, I noticed that the tiles you put in an array don’t count as actual tiles in the editor. could you please change that in a future update?

Unfortunately, it is not possible for my extension to add tiles to the internal Makecode tilemap editor, because that tilemap editor makes its own list of tiles which I cannot change or add to.

When you add images to that array, it is telling the tilemap code which image should be drawn for each number in the list. The built in tilemap editor automatically does all that for you, including adding the tile images that you use in the stored tilemap, and editing extension code cannot change the code of the tilemap editor, nor the code that it automatically generates in the tilemap.g.ts file.

1 Like

got it, but does this mean you can’t run tile events on generated tiles?

1 Like

I will look into this…

1 Like

I found a weird bug… or maybe feature? Apparently tilemaps generate an extra row of tiles around the tilemap! You usually wouldn’t see this because the camera is locked inside these blocks and because even if you generate a tilemap smaller than the camera, these tiles are tile #0, which is normally transparent! I suspect these are there so that they didn’t have to code in the player colliding with the edge of the tilemap (lol). Then again, even outside of these extra blocks, sprites still act like they are inside walls, so who knows why the extra blocks are there??

Anyways, if you use my extension to make tilemaps that are smaller than the camera, this is why there is an extra layer of tile #0 around the tilemap. You can fix this by making tile #0 a transparent tile.

1 Like

Looks like it’s completely possible! You can drag an “(image)” block into the place where the “(Tilemap image)” block goes!
Demo: https://arcade.makecode.com/S62178-71772-40713-56937

1 Like

WAIT A SECOND!!! Could you maybe generate a tile map from this? If you get the stringified JSON and save it with settings then regenerate it with Pxt-TilemapGen? Please tell me if I completely misunderstood something (I probably have)

1 Like

Yes. That’s what the extension is for.

About the quote you have there, idk why they are using stringifyed JSON to save tilemaps. That’s not even how they are saved in Makecode at all. That’s way too many characters per tilemap file and would take up so much space! What that user found was the function I’m using when I generate tilemaps. The buffer is a string of all the tile IDs in the tilemap, for example tile “0” is the transparent one, and “1” is the first one you create, etc, left to right top to bottom. Then the “layer” is an image where any filled pixels are walls in the tilemap and transparent pixels are… not walls. So yeah, idk why they wouldn’t just… save the tilemap data? They don’t have to use strings…

2 Likes


I don’t really understand… We have the tile map data, can we not just load that? If we generate our own tilemap, surely there is some way to access this during run time. I have probably badly misunderstood something.

1 Like

I will certainly look at it again when I have a computer. I forget when I learned how to access “protected” variables, so I may have not known how at that time and it might be possible for me now, idk. You can just copy the data and use something like Buffer.base64() to decode it into a buffer… idk where the layer (wall) info is in that data, it’s been a long time since I looked at that stuff.

2 Likes

The wall data is in tilemap.g.ts