Skip to content

Instantly share code, notes, and snippets.

@Achie72
Created June 22, 2024 17:38
Show Gist options
  • Save Achie72/1b309c34c6441296d016107c1f113093 to your computer and use it in GitHub Desktop.
Save Achie72/1b309c34c6441296d016107c1f113093 to your computer and use it in GitHub Desktop.
PICO-8 load maps from strings
-- For this I whipped up my good ol’ reliable approach of having the following functions:
-- export the currently drawn map to the clipboard
-- I used this in copied .p8 files to draw levels,
-- run them and copy the given string into this main
-- file's map collection
function export_map()
-- start with empty string
local mapString = ""
-- loop over the map tile by tile
-- and append tile numbers by , after each other
-- this will give back a string similar to what
-- you can see later in the map collection
for x=0,15 do
for y=0,15 do
mapString = mapString..mget(x,y)..","
end
end
-- paste the string onto the clipboard
printh(mapString, '@clip')
end
-- With this you can setup a collection inside init that is holding all your map string one by-one.
map_collection = {
"0,0,0,0,0,0,36,0,0,21,18,45,14,18,47,14,0,36,0,0,0,0,0,0,0,21,61,18,18,45,18,18,0,0,0,1,19,14,14,0,0,0,5,5,18,18,14,14,0,0,0,2,12,19,18,0,36,0,0,0,18,18,18,18,0,0,0,14,19,62,18,0,0,0,0,4,18,18,61,18,0,37,0,62,19,19,18,0,0,0,21,18,45,18,18,47,0,0,0,2,19,14,18,0,0,0,21,18,47,18,45,18,0,0,0,14,19,14,18,0,0,0,21,18,18,18,18,14,0,0,0,2,19,19,18,0,0,36,21,18,14,18,18,18,0,0,0,2,14,19,18,0,0,0,21,18,18,18,18,61,0,36,0,45,19,19,14,0,0,0,21,18,14,18,14,18,0,0,0,2,14,30,18,0,0,0,6,18,14,14,18,18,0,0,0,3,45,19,14,0,0,21,18,14,18,18,14,14,0,0,0,0,0,0,0,0,0,21,18,18,18,61,18,14,0,0,0,0,0,0,0,0,0,21,47,18,18,45,18,14,0,0,37,0,0,0,0,36,0,21,18,18,14,18,18,18,",
"0,0,0,0,0,0,36,0,0,21,18,45,14,18,47,14,0,36,0,0,0,0,0,0,0,21,61,18,18,45,18,18,0,0,0,0,0,0,0,0,0,0,5,5,18,18,14,14,0,0,0,18,18,30,14,0,36,0,0,0,18,18,18,18,0,0,0,2,14,2,14,0,0,0,0,4,18,18,61,18,0,37,0,2,12,2,18,0,0,0,21,18,45,18,18,47,0,0,0,14,19,19,14,0,0,0,21,18,47,18,45,18,0,0,0,0,0,0,0,0,0,0,21,18,18,18,18,14,0,0,0,0,36,0,0,0,0,36,21,18,14,18,18,18,0,0,0,0,0,0,0,0,0,0,21,18,18,18,18,61,0,36,0,14,14,18,30,0,0,0,21,18,14,18,14,18,0,0,0,14,2,14,2,0,0,0,6,18,14,14,18,18,0,0,0,2,12,18,62,0,0,21,18,14,18,18,14,14,0,0,0,14,19,45,18,0,0,21,18,18,18,61,18,14,0,0,0,0,0,0,0,0,0,21,47,18,18,45,18,14,0,0,37,0,0,0,0,36,0,21,18,18,14,18,18,18,",
}
-- The long strings basically contain every tile of the first screen (0,0) - (15,15)
-- where we draw all our maps (the very first one screen region of the map-editor).
-- Having this string your only need is to setup a level variable and then the following two functions:
-- load map from a string. This string is stored in map-collection
-- and mapIndex is the passed level counter number.
function load_map(mapIndex)
-- fetch the mapIndex-th element of the map collection
local mapString = map_collection[mapIndex]
-- init x,y
local x,y = 0,0
-- split the fetched string into numbers, so now it is {1,2,3,4,5} array
-- instead of "1,2,3,4,5" string
for tileId in all(split(mapString,",")) do
-- iterate through each tileId (1,2,34, etc..)
-- and handle them correctly
-- the only tiles which we use as specials
-- are gonna be the spirits = 12
-- the mushrooms and the flips for the mushrooms
if tileId == SPIRIT_TILE then
-- if it is a spirit, spawn one on the coords
-- and reset the tile to a grass (entities)
-- I draw with sprites instead of tiles
add_character(x, y)
mset(x, y, 18)
elseif tileId == MUSHROOM_ON_TILE then
-- spawn a grown mushroom
add_mushroom(x, y, true)
mset(x, y, 18)
elseif tileId == MUSHROOM_OFF_TILE then
-- spawn an ungrown mushroom
add_mushroom(x, y, false)
mset(x, y, 18)
else
-- just set the tile accordingly
mset(x, y, tileId)
end
-- iterate y first because most double for
-- cycles read in as column by column
y+=1
if y > 15 then
y = 0
x += 1
end
end
end
-- The pair of this function is the unload, that handles deleting everything you do
-- not want to bring over to the new stage, which are usually the actors, particles.
function unload_map()
-- empty all the arrays
character = {}
particleCollection = {}
mushroomCollection = {}
-- reset all the tiles on the
-- screen
for x=0,15 do
for y=0,15 do
mset(x,y,0)
end
end
end
-- With this all setup we just need to modify our code a little bit.
-- When you win a stage, instead of going to the menu, we unload the map,
-- add one to the level counter, call load_map(level) and set the state to game so we can play again!
-- I now can duplicate my .p8 files, so I have level_1.p8, level_2.p8,
-- draw the according level in the cart, run it (as export is run during _init()
-- in my case but you can do it in button press) and paste the new string into my map_collection.
-- And bam, as many levels as you can fit into the string limit!
@Achie72
Copy link
Author

Achie72 commented Mar 16, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment