Any chance you could work a little wizardry with Emscripten and get those 64-bytes of save data to actually store somehow in the HTML5 player? With Emscripten's virtual filesystem you could mount a cdata folder from localStorage or something, right?
Confirmed. Cartdata does not persist in the web player exported with export(), but does in the full standalone app. Local storage would be good.
Theoretically, the self-selected cart IDs are insufficient for the BBS, since they'd allow for cart impersonation. Would be sad if someone tried to grief saved data with malicious carts. An obscure and unlikely bug could even allow for cart worms! :) The defeat is probably registered devs and signed carts, but I don't know if it's worth going that far. Using the BBS-assigned cart ID as the cart ID might be fine, though a new version of a cart couldn't see the cartdata of a previous version.
cartdata("test_cartdata") for i=0,5 do print(i..': '..dget(i)) end for i=0,63 do dset(i, i*3) end print('updated.')
On first run, prints 0's. On reload, when cartdata persists, prints multiples of 3.
Fun edge case: the "reboot" button in the web player does demonstrate persistence, but actually reloading the page does not.
For the web player hosted here it could simply be keyed to a (username,cartname) tuple. This way names are perfectly free-form, but you won't be able to mess with save date for carts you didn't author... modulo unicode bugs.
If that's not complicated enough, there could be a system to allow updates from approved authors. ;)
Yeah, using localStorage should be sufficient for most purposes (since on other websites they wouldn't be able to access the same data as unrelated websites) and for this bbs specifically having it keyed to a specific uploader/author names would do the trick (mind you, the cartdata() call would still be able to distinguish the different carts of the same author!) But I wouldn't really be concerned about malice, since we're all such nice people anyway? Carts don't autoplay unless you click an autoplay link or anything, either, so...
Plus none of the games on the BBS that I've seen so far actually use save data to begin with, since Pico-8 carts are too strictly limited to have a long-running game at all... x_x;
It would be way useful for multi-cart RPGs, though. Like, you reach the end of one cart's dungeon or whatever, it logs your levels and whatnot into the save data and tells you to go to the next cart, you scroll down a bit and click the play button on the next cart and it picks up from right where you left off using the same cdata name. That would be perfect.
After significant testing, I've determined that carts actually only save when the Pico-8 returns to the console view, eg. the program terminated normally. Which wouldn't happen if you refresh the page in the web client!
Oh wait. I forgot dddaaannn's test above also exits to console (it doesn't have a game loop). Nevermind, then.
I was trying something weird and discovered an unrelated problem. When you use run() from within your cart, the save data doesn't actually write to disk, you see. Even though you'd expect it to? It just sort of gets reset to 0 with everything else, even if you did call dset a couple of times...
ETA: Actually this solution isn't as good as I thought! A query string can reference a particular comment on a page, rather than the original post, and still bring up the same view. A url-based namespacing scheme COULD work with only
window.location.pathname (and without
window.location.search) if pathnames were unique per thread, which isn't currently true on Lexaloffle.com.
OR, the namespace could rely on the Cartridge's ID number, though I'm not sure if it would be easy to let the web player know about that number.
I'd like this to be included in a near release of pico-8, if possible.
The problem of properly and securely namespacing cartdata on a shared domain is interesting. It seems the best solution is to include the page location as part of the localStorage key. This way, if two separate games happen to be called "Dragon Hunter," one will store its localStorage data under the "dragonhunter/bbs/?tid=2368" namespace and the other under the "dragonhunter/bbs/?tid=3241" namespace.
What that also means is if a cartridge author has shared multiple versions of a game on the same discussion page, assuming the cartdata namespace is the same, those versions will share game data (which is probably a good thing as long as the author hasn't introduced breaking changes in the data storage scheme).
window.location.pathname + window.location.search. It would be ideal not to have to include window.location.search, since we might want to use the same data store for different URL query strings, but lexaloffle's location scheme relies upon the query string for uniqueness (this isn't the best routing design, but it would be on Zep to re-configure it). Alternatively, the key namespace could only rely upon the "tid" query parameter, but that solution assumes the namespacing problem would only ever exist on this website, which probably isn't a good thing to assume.
[Please log in to post a comment]