demo cart
This demo shows off the interface, but you'll need to download bigmap to use it for your own games. See "setup" below.
motivation
The recent 0.2.4 release added support for larger maps:
> Similar to gfx memory mapping, the map can now be placed at address 0x8000 and above (in increments of 0x100). This gives 4 times as much runtime space as the default map, and an additional POKE is provided to allow customisable map sizes.
Larger maps are now possible, but it's difficult to get them into memory -- the built-in map editor only works with vanilla-sized maps.
This cart is a full recreation of the pico-8 map editor (with some nice tweaks) that makes it easy to make these larger maps.
features
- tight iteration loop - play a level in your game, jump into the map editor to make a small tweak, and return to the game with minimal friction
-
- change map size at any time
-
- max width: 256 tiles
- max height: none
- max total size: 32K tiles (e.g. 128*256, or 32*1024)
-
- easy copy-paste (right mouse + drag to copy a "brush", left mouse to paste)
- large brushes - place multiple tiles at a time
- zoom in/out
- show 16x16 "room" outlines (useful for carts like celeste that are made of many 16x16 rooms)
-
- "transparency" - optionally ignore sprite 0 when pasting large brushes
-
- compressed maps using PX9
- autosaving
- the map editor costs 0 tokens -- it's a completely separate cart that you only use during development
(your game needs just ~300 tokens to load the map string and run the decompressor) - your game will be splore-compatible (bigmap does not use multi-cart)
- your game can call
map()
,mget()
,tline()
etc without any extra work
undo/redo?
The editor currently has no undo/redo functionality. That's not ideal!
To undo all changes since your last save (probably the end of your last session using bigmap), use the "discard changes" button in the top-right.
If you make a large mistake, replace map.p8l with an autosaved version (inside mygame/autosave/
) and reload bigmap.
setup
Setting the bigmap editor up takes a bit of work. This is mainly necessary to enable a tight iteration loop, and also to work around the restrictions of pico-8 (for example, it's impossible to read a file from disk without user interaction, but asking the user to drag-and-drop a file every time they want to edit their map is way too much friction for my taste)
To start, make sure you have a folder (e.g. mygame/
) with your game cart inside (e.g. mygame/mygame.p8
)
cd mygame
(navigate into the folder containing your game)mkdir autosave
(create a folder to store backups/autosaves)printh("","map.p8l")
(this creates an empty map.p8l file)- Save this file (https://gist.github.com/pancelor/f933286f244c6b85b7720dbe6f809143) as
px9_decomp.lua
(inside themygame/
directory) load #bigmap
(note: this is different from the#bigmap_demo
cart, above)- Uncomment the two
#include
lines in the second tab (tab 1) save bigmap.p8
-
Paste this snippet into
mygame.p8
: (inside_init()
, or at top-level; either works)menuitem(1,"▒ edit map",function() -- pass spritesheet through upper memory, -- avoiding an extra second of load time local focusx,focusy=0,0 memcpy(0x8000,0x0000,0x2000) poke(0x5500,1,focusx,focusy) --signal load("bigmap.p8","discard changes","mygame.p8") end)
(make sure you change "mygame.p8" to the actual filename of your game)
This snippet adds the menu option to enter bigmap while playing your game. You can tell bigmap to launch at a particular map coordinate (e.g. the position of the player) by setting
focusx
andfocusy
. - Paste this snippet into
mygame.p8
at top-level:#include map.p8l #include px9_decomp.lua if map_import then map_import() end
- Save
mygame.p8
You should now be good to go!
test+edit iteration loop
- Save
mygame.p8
. any unsaved changes will be lost every time you launch bigmap. (I wish this was avoidable but I couldn't find a way around it that preserved the quick test+edit loop I wanted) - Run
mygame.p8
- Pause the game (with P or Enter)
- Choose "edit map" to load bigmap
- Edit your map inside bigmap
If you accidentally press escape and exit the map editor, typer
orresume
into the console to resume the map editor. - Return to your game with P, Enter, or the clickable "Play" button in the top-right

I advise setting up mygame.p8
to jump you to the room you were editing when it starts - this can be done by reading the focusx
and focusy
global variables that are set inside the map_import()
function (inside the map.p8l
file that bigmap generates) and spawning your player at that position.
See my celeste mod or the getting started video above for an example of how to do this.
technical details
When you press the save or play button, bigmap uses printh
to write a text file called map.p8l
into the current directory. This text file happens to be valid lua code that defines a function called map_import()
, so when mygame.p8
executes #include map.p8l
and map_import()
, it runs the code generated by bigmap.
Here's an example of what map.p8l looks like:
-- this file was auto-generated by bigmap.p8 function map_import() focusx=11 focusy=12 mapw=128 maph=64 poke(0x5f56,0x80,mapw) local function vget(x,y) return @(0x8000+x+y*mapw) end local function vset(x,y,v) return poke(0x8000+x+y*mapw,v) end px9_sdecomp(0,0,vget,vset,"◝◝◝ユ◝7な◝◝✽,ゃf\0★)&るちP;](♥KねF ... many many more chars here ... X▤ミヘラ⬇️⬇️Bれん") end |
This has 3 main parts:
- Set up some helpful global vars -
mapw
andmaph
are the width and height of the map, in tiles.focusx
andfocusy
are the tile coordinate of the tile that was in the center of the screen whenmap.p8l
was saved -- you can use this info to jump directly to that room to let you make small tweaks and test them very quickly poke(0x5f56,0x80,mapw)
-- this tells pico-8 to use mapdata stored at 0x8000, with map widthmapw
- The rest of the function uses PX9 to decompress the binary data stored in that long string. The decompressed data gets stored starting at 0x8000 and takes up
mapw*maph
bytes.
That compressed data string is created using PX9 and this snippet for encoding binary data in strings.
alternative map editors
I like bigmap but other map editors make different tradeoffs, and you might prefer one of them instead:
- https://www.lexaloffle.com/bbs/?tid=42848 -- make larger worlds out of metatiles
- https://github.com/ExOK/Celeste2/ -- you can see in their source code how they make maps in individual carts and then combine+compress them all together into a single cart before release
- https://github.com/samhocevar/tiled-pico8 -- use Tiled (an external program) to edit vanilla pico-8 maps. consider combining this with the Celeste2 method
credits
- bigmap by pancelor: https://pancelor.com
- PX9, used for compression: https://www.lexaloffle.com/bbs/?tid=34058
- zep's string-packing snippet: https://www.lexaloffle.com/bbs/?tid=38692
- sprites used in bigmap_example.p8 (shown in the setup video): FROGBLOCK by Polyducks: https://polyducks.itch.io/frogblock
While making bigmap, I simultaneously used it to made a celeste mod called "La Sal" to make sure that bigmap felt good to use. Check it out here: https://www.lexaloffle.com/bbs/?tid=46224
happy map editing!
I'd like to see what you make -- let me know if you use this in your projects! It's free to use, just credit me and link back to this page if it helped you out :)
Is bigmap helpful? Is it too confusing to set up? Find any bugs? Let me know what you think!



@SandwichBlam @GeKStudios I tried to explain it under the "usage guide" section -- is there a specific part about it that's confusing?
(note that you have to download the bigmap cart with load #bigmap
; the web demo playable here is just a demo to get an idea of what it's like to use the editor)



changelog for v1.2:
- clarified some things (e.g. map size limits)
- added a video guide on how to set up your project with bigmap
- the base cart I start from in the video is available to download (
load #bigmap_example
)
- the base cart I start from in the video is available to download (
- thanks to @Peteksi for helping me fix two bugs!
- thanks to @freds72 for pointing out some issues with the compression! (now fixed)
If you've already started using bigmap, you'll want to download the latest version (load #bigmap
) and also download the updated px9_decomp.lua script



Hallo pancelor!
after a little bit, I got bigmap up and running on my pico-8! this is a really cool tool, and now we can make huge celeste carts like the works of taco360 due to the nonexistent map hight size! very nice!
:)
(one note: when I had to set up the .lua file, I had to copy the code into notepad and save it as a .lua. that was confusing, as I first tried to save it as a .lua from my pico-8 and it became a .lua.p8.)
edit: I do NOT know how to use github. XD



can this be used with an Evercore celeste file? as in, setting the level width, height, x, and y, and it would work?



I don't know what evercore is @SandwichBlam, but bigmap should be able to work with it -- all bigmap does is edit the map data of a cart.
you might have to do extra work to make them work nicely together, but I would think it should be the same as any other cart. follow the "setup guide" video and let me know if you have questions!



Evercore is like a sort of bigger map addition to celeste classic.
If you've played Fault, those scrolling levels are what evercore adds you have to specify the level height, width, x, and y. so, I'm not sure if that would work with an external map editor...



It doesn't work for me, when i try running my game or bigmap i get the "could not #include file: px9_decomp.lua"



@Redstoner158 sounds like you didn't save the file from step 4 to the right place, or maybe you saved it with the wrong name. what does your filesystem look like -- what does ls
output when you're in the mygame directory?



@pancelor, could you allow map height up to 32768\W instead of 256 ?
I'd like to work with W=16 and H=2048 personally.



@pancelor I want to use this for a future game I'm making, but I want to have multiple maps stored/loaded during runtime. How would I implement that with this editor?
Maybe I could find a way to get the map data that the bigmap editor exports and store them into variables to switch between? Idk



I also ran into this error while using the game:
runtime error line 22 tab 0 return x<target and min(x+delta,target) or max(x-delta,target) attempt to compare nil with number |
and I keep running into this error when I pan the map around with the mouse.
Edit: It got fixed after I went back to my game and back to the editor
Edit 2: Nope, it's still not working



@Beanos123 multiple maps should be doable; you'll want to modify bigmap to produce multiple different functions instead of just map_import()
(maybe map_import_forest()
, map_import_dungeon()
, etc). search for function map_export
to see where that happens. then inside your game when its time to load a level, call whichever import function you want. hope that makes sense.
and maybe modify the menuitem in your game from load("bigmap.p8","discard changes","mygame.p8")
to load("bigmap.p8","discard changes","mygame.p8,forest")
then modify bigmap to extract the levelname from the stat(6)
parameter string
so, multiple maps should be possible BUT note that you'll probably run into the pico8 compressed-size-limit really quickly if you have multiple huge maps, so it might not actually be a good idea.
and about that error: odd, I've never seen that. search for this code:
local x=widget.tpx local y=widget.tpy |
and change it to this:
local x=widget.tpx or 0 local y=widget.tpy or 0 |
hopefully that will solve the issue. I looked at the code and don't see how tpx can possibly be nil, but I could be missing something. a video or a full cart + reproduction steps would help (email me at [email protected] if you'd like), but this quick fix might be good enough
or check out my printh tutorial for more tips on tracking down the bug



The mouse movement works for me now, thank you :].
As for the multiple functions, I was thinking about storing the exported strings into Lua memory, to not run into the compressed size limit. It's possible.



> storing the exported strings into Lua memory, to not run into the compressed size limit
that doesn't make sense, Lua memory doesn't exist in the cart file, and the data has to be stored in the cart file somehow. maybe you mean in the spritesheet/map/etc, the ROM area of the cart? that would avoid the compressed limit but would make working on the cart harder. (actually, bigmap will probably have problems if you overwrite the sprite ROM)
but anyway yes, it's possible, just want to make sure you're aware that the pico8 limits still exist and this doesn't let you make worlds arbitrarily big (and, that's a good thing! the pico8 limits are great)
For reference, La Sal (my celeste mod that I made with bigmap) uses 2763 chars to store the map. I stored it in a string, but that would use about 33% of the map ROM (0x1000-0x3000) if I stored it there instead.



Sorry, yeah I was mistaken about Lua memory. I'm just trying to spitball some ideas to save on chars.
[Please log in to post a comment]