Log In  

I have two issues with the ls() function. Any help with them or workarounds would be highly appreciated!
Also hello! This is my first post!

Custom File Extensions

I am making a game that involves a level editor. I have the code save these packs of levels with a custom extension using cstore(), one that is different than .p8. It saves just fine, as it's technically a .p8 file with a custom extension. For the sake of argument, let's say the extension is "levels", so my cstore() looks like:

cstore(0x0, 0x8000, 0x4300, filename..".levels")

I'm also able to load from that created file, like so:

reload(0x8000, 0x0, 0x4300, filename..".levels")

The issue I am now facing is that I want to be able to list all of the files in the directory that have this custom file extension, so that the user can choose the level pack to play. However, the ls() function only returns files that end with .p8 and .p8.png. Is it possible to have it list only files with a certain extension, or at least list all files?

I don't really want to save my level packs as .p8 files, as they aren't really a runnable cartridge. They are a bunch of garbage graphics data with no code. And even if they are technically still a cartridge, I don't want them showing up in splore's root file browser or something like ES-DE, and I want my game to easily know which are level packs it can read.

Working Directory

My game is in a subdirectory in the root folder of pico-8 while I develop it, like so:

/mygame/mygame.p8
/mygame/main.lua
/mygame/map.lua
/mygame/util.lua

When I do the above cstore(), the file is created in the subdirectory that the game is running from:

/mygame/mygame.p8
/mygame/levelpack.levels   <-- here
/mygame/main.lua
/mygame/map.lua
/mygame/util.lua

But if I do ls() in the game, it looks in the root folder only:

mygame/

I get that I could do ls("mygame"), but once I export it to .p8.png, it probably won't be in a subdirectory anymore. Is there a way that I can tell ls() to look in the directory that the game is currently running from? Or, a way to get the current working directory so I can pass it to ls()?

P#142371 2024-03-03 22:10 ( Edited 2024-03-03 22:10)

here's code that prints every file name visible from the cart's root directory.
I suspect that ls() seeing your levels or not does not depend on extension, but just on whether they are in the current directory or not.
there is no pico-8 cd() function, and no extcmd("cd /whatever/") workaround either, so I'd recommend avoiding relative path.

function tree_ls(path)
   local t,i,name
   t=ls(path)   
   for i=1,#t do
     name=t[i]
     print(path..name)
     if name[#name]=="/" then
        tree_ls(path..name)
     end
   end
end

tree_ls("/")

About file extension, .level.p8 and .level.p8.png would make sense to me. Bonus points if your png image actually looks like a thumbnail of the level and calls the game with itself as parameter :p .

P#142380 2024-03-04 01:06 ( Edited 2024-03-04 01:20)

Thank you for the recursive ls() method! If I can't get the working directory of the running cart like cstore() apparently has access to, I'll probably use this to just fetch all of the level packs existing anywhere on the PICO-8's virtual drive.

However, the official documentation for ls() says that it only lists .p8 and .p8.png files:

LS([DIRECTORY])

List .p8 and .p8.png files in given directory (folder), relative to the current
directory. Items that are directories end in a slash (e.g. "foo/").

When called from a running cartridge, LS can only be used locally and returns
a table of the results. When called from a BBS cart, LS returns nil.

Directories can only resolve inside of PICO-8's virtual drive;
LS("..") from the root directory will resolve to the root directory.

So in order to list files with a custom extension (".levels" for example), I would need some other solution. It's interesting though, if you start typing load and a directory name, then press tab, it will show every file in that subdirectory. So I know PICO-8 can see those files, it just doesn't show them in the ls() command. Which is a bummer.

I had considered using ".levels.p8"/".levels.p8.png" with a call to my game, however I don't think there's a way to save actual code to a cartridge, nor a label. The user would be using my game to create, modify, and save level packs, so no opportunity to set a label and the code inside to launch my game from it. Hence why I figured just using my own extension.

P#142431 2024-03-05 01:42

I think a lot of experimentation is in order. You can't add code to an existing cart, but you 100% can create a valid minimal .p8 from scratch that includes label and code with printh . You can then edit the data with cstore()
There's also extcmd("label") that unfortunately only saved the label to the cart when calling save from the command line last time I checked, but a lot of secret functionality keeps being added to pico-8, so I wouldn't be surprised there's a way to use it somehow.

When the level designer wants to edit his already existing level, you'd get the data with cload, edit in memory, and to save, rewrite the p8 from scratch with printh and true as last parameter to empty the file, then printh to write the label and code, and finally cstore to write the updated level data.

P#142462 2024-03-05 16:11 ( Edited 2024-03-05 17:09)

Oh, I forgot about printh()... yeah that could work! I'll have to mess around with that. Thanks for the pointers! Creating valid cartridges means I don't need to use my own custom extension, and thus my first ls() issue is moot. I still would like to know the working directory of the running software to make the level pack selector better, but I'm probably just going to use the root of the PICO-8, for loading and saving simplicity.

Edit: Hmm... it seems as though doing printh("(cartridge header string)", "filename.levels.p8", true) saves the file as filename.levels.p8.p8l. I'm not sure what a p8l file is, and the PICO-8 documentation doesn't mention this? The contents of the p8l file look good, but it's not a p8 file so I'm not sure if that's usable.

Edit edit: Looks like ls() picks up these p8l files, and they are considered a cartridge, so I guess we are all good!

P#142477 2024-03-05 22:56 ( Edited 2024-03-06 00:01)

[Please log in to post a comment]