So, this may not work in future versions of Pico-8, but right now, I've noticed that if you do a load() within your game game code, you still have your base ram untouched until you run run(). With that info, you can use objelisks technique (https://www.lexaloffle.com/bbs/?tid=1860) and use cstore(x,y,z) and some empty space in the spritesheet to transfer info from one cartrige to another. Then use run() to switch to the new cartrige and peek to read back the transfered info. A single sprite equals 32 bytes with is good enough for a metroidvania.
As I said, there's no guarantee that load() will work like that in the future and it probably wouldn't work like that on a "real" Pico-8 console, so in a way it could be considered cheating. But right now it works.
A very simple game I made while getting used to Pico-8 commands and api.
v 0.0.4 :
v 0.0.3 :