A bit of sad, I spent the last three weeks with creating a small rpg game with Pico8, but ran out of memory half the way. I would have been able to come along with the token count with some tricks, but finally, the compressed cartridge size limit hit me and I don't see any chance to finish it with the current limits of Pico8. If the memory limit for the source code would be doubled, there would be a chance, but until then, maybe the wip is of some fun for one or the other. As I'm toying around with a fantasy console like Pico8 myself, maybe it will see the light there eventually ;)
The game picks up elements from the early Ultimas and The Bard's Tale. You can move around the city, enter some buildings and you can enter the first two dungeons. There is already a world with some other buildings and dungeons, but as there's no memory left, I'm not able to fill them with game play.
So far, have some fun with it!
Update: Seems, the cart was that too big, that the export failed - uploaded again.
Update2: I fixed two missing features, where you weren't able to leave the shop and the inventory. Further, I unlocked the wilderness and all the other dungeons.
Actually, I'm planning to finish it, but there is no chance to do this on the Pico-8 at the moment. Although I'm already (again) high in the token count, there is still potential to save up to 1000 tokens by moving the dungeon logic into strings, making it possible to finish the review board, the inventory the shops and even extending the battle system a bit.
But it is the compressed cartridge size which makes continued development impossible on the Pico-8. It would need to be doubled to fit all the dungeon logic into the game, I haven't known about this limitation as I designed the game. The only limitations I was aware of were the 8192 tokens and the 256 kb of code. That the final cartridge size is limited far before the 256 kb of code came very sudden to me, as Pico-8 showed that up during saving.
But I don't plan to dump the game, nothing like that. As I mentioned, I spent thoughts and work on a fantasy console myself, which would be "of the same generation, as Pico-8 is". Means, same resolution and color specs and similar limits - but with "real" cartridges, bigger than the system RAM, as all those consoles of that time had compfortable sized cartridges. Further, my system (called Nano-89, website coming the next days I hope) uses a "real" CPU designed by me some time ago. I'm currently finishing the CPU with the graphical output already working. Editors, like in Pico-8, are to be expected later., but one will be able to import the graphics data of Pico-8 really early.
I hope, zep doesn't get offended by mentioning this and I don't see Nano-89 as a replacement, but as the "other" system of that "generation". Loved computers always had a competitor - the C64 the Atari XL, the Amiga the Atari ST, the Nintendo the Sega and the PlayStation the X-Box. And the aims and concepts are some kind of different anyway - I want to create a real fantasy hardware, as Pico-8 aims for creativity by limitations.
Could you not store additional data in a separate cartridge? reload() and cstore() both accept an optional parameter for the name of another cartridge, though I haven't tried it myself. It wouldn't work on the web player (yet) but you'd be able to continue the PICO-8 version
Sadly, that wouldn't help me out in any way. It is really the amount of code which is the central problem. Actually, I don't understand it myself - it is stated, that with the 0.14, the possible amount of code raised to 64kb, but it limits at 36kb for me yet. If I would have the promissed 64kb of code, finishing the game would be a piece of cake. Mostly everything is implemented and only needs to be finished.
Using a second cartridge would only help me with extending the graphics, but that never was my problem. Sure, the artworks consume a lot of sprites, which could be used to improve the maps, but yet this works well for me. I really need more code space for the menus and the game logic.
As I already critized in another thread, there even is no way to create some game data within the user space, as you are not able to store the user space. So adding more tiles and more maps wouldn't result in more game.
So, for the time being, I'll stick to the Nano89 project, which goes forth well. I was able to mount a first cartridge tonight and will continue to implement the graphics unit now. The PICO-8 version will continue in development on the day, when the code space issue is solved. I really would love to finish it on PICO-8 as well as on Nano89, believe me!
@0xabad1dea: Yes, I know, it's a know issue, which arises from recycling some global variables. Replacing them with differentiated ones consumes coding space, which is exactly the problem I have at the moment. But I'll take a look, maybe I can fix this by ripping out the save ability (Not any useful in this state anyway), making free some bytes for this.
It's realy a cool game, a lot of content and thing to do. For your issues with the compressed limit, you could use some "sfx" space to store some of your strings. I also struggle a little with that limit and that as been realy effective. I use a second cartridge to store and encode my datas in the sfx space (using poke), do a cstore() and save the result. I then use a text editor to copy the song data in the game cartridge. You can do simple function that give you back a specific string using an offset in the memory. I can post some sample function if you want.
Beside this technique, I think there is some code that could be merged together, and using tables and function "pointers" to factor it.
Thanks for all the suggestions, there are finally developing some plans in my head to bring the game at least a bit further. First of all I'm currently transfering the interaction logic for the map into a table, a step which was already planned. This should already give me over 1KB of RAM. Second, I can save some bytes by making my table-packer a bit more compact, the potential for 100 or more bytes lies there. The next step would be a rewrite of my menu utilities from scratch - currently, the item list and the general menu are two seperate code bases, those can be merged with some effort. This should make some more bytes free. From there I need to look, if this fits somehow into one cartridge or if I need to go for a two cartridge solution. I don't like this approach, as it doesn't fit the concept of a console, having two cartridges at the same time, but on the other hand, this opens a lot of opportunities, like using the first cartridge as a boot cart and the second for a gaming cartridge. The first one could store the interaction data and load it into the RAM, holding a more complex intro as well. I just have to see.
Actually, it is a real pitty, that there is no real ROM in the cartridge for game data. I don't want to use the sound space, as I hope to add some music and sound effects eventually and having to work around the fixed dedicated memory blocks without some versatile ROM is a real pain.
Meanwhile, working on Nano89 progresses as well, but as I'm hardening the CPU with a ton of unit tests, there isn't much to see at the moment...
Update: Funny effect - by moving the logic-based code for the maps into a generic table, the compressed size of the source code raised... Really. This compressed source size limit simply sucks.
Best thing to do is send the cart to zep, He already asked me to send him a cart demonstrating a CPU bug I found.
Send 2 carts - one with the limit problem, and another cart with the compressed size raised after you moved the logic to tables.
I finally restarted the project with a different approach, now I really use two carts (at least, may span over three in the end), where I use the memory of one cart for storing game data in a serialized format and a title screen only. The cartridge is written with a custom python script, which does serialization of a python data tree and a custom compression, compareable with a naive huffman encoding (gives me 33 percent more space). On cart 2, the sprites and maps are stored, works fine yet. I even moved a lot of logic code into the data structure. The only two drawbacks are, that this will hit the 512kb memory limit sooner than later, so I have to add some kind of swapping mechanism, which is good for issue 2 as well. Using this memory intensive approach makes a later port to Nano89 pretty hard, so having a bank switching in there already, makes even this easier.
I already recoded the cut scenes, the basic map logic and the temple, with the review board next, so things look pretty well at the moment. Sadly, I was down the last week due to a flue, so not as much progress as I originally hoped for...
By the way, the baby has a name now:
A bit late perhaps since it sounds like you've found a more dramatic solution to the compressed size, but maybe useful for others:
You can use a lua minifier (such as https://mothereff.in/lua-minifier) to significantly reduce the size of your compressed code. I have a cart that weighs in at ~32k characters, ~12kb compressed; the minifier was able to get that down to ~15k characters and ~6kb compressed. (YMMV obviously; the original code was amply commented and not optimized for size.)
The minifiers I've tried will choke on pico-8's nonstandard language extensions like
if (this) doThat() and +=/-= operators, so you'd need to stick to vanilla lua syntax.
Thanks, definitely a good idea, but from the current perspective, this wouldn't helped me very far. At the moment, I compile 16k game data into the first cartridge, with no end in sight, as I'm only recreated most parts of the original approach yet. There is no additional game data yet, although I implemented most screens and menus already. Due to the illustrations, I definitely will need three cartridges anyway.
Thank you for your interest in the game!
Yes, I'm working hard on getting the rework done and the reimplementation already surpassed most of the features of the first one. Currently, I'm working on the battle and magic system. Things go along very well, although the token count is still a hard limit. I hope to get the basic implementation done within the next weeks to start with the game design itself by filling up the dungeons. The game uses three cartridges at the moment, storing almost 30kb of game meta data alone. I will update the game as soon as the gameplay and game design of the city itself is complete!
Hello SunSailor, my name is Rudlin.
You probably don't know me (I'm pretty much a nobody/lurker in this community), but I have seen your work, and I am simply enamoured. I'm working on an RPG as well (only 1 cart at the moment, though). I've checked out your fantasy console, Nano89, and I must say, I'm very excited to see it released.
I would like to ask you, as someone who seems to be very active in this community, along with your adventurous and innovative use of multi-cart threading (if I may coin the phrase), would you say Pico-8 games will begin to become longer in the near future, or do you think they will stay within their "arcadey" formats many developers seem to prefer at the moment?
Thank you, and good luck in your current and future endeavours.
It's not just you. I hit the token wall about halfway through Gentroid too. There's definitely a pretty universal need to double the code space; and I think to rearrange the SFX/Music editor so that you have the same space, broken into "twice the amount of half the size chunks;" seeing how song structuring works.
Rudlin: I think due to the constraints, they HAVE to remain arcadey-format. There just isn't room for anything of bigger scope than that. I'm doing all kinds of preplanning and scope-crunching just to do abridged demakes of 8-bit stuff, and I'm still looking at it like "I'm gonna hit the wall before it's done, I just know it."
PS: I played... and... there's a lot still busted in this right now. I can travel south through anything, buildings that are obstacles are identical to ones that aren't... I walked south through the entire overworld and into the store prompts. XD
And if you scroll the items menu down past the bottom, you can overlap the entire store prompt with the last item, then choose the price you'd like to pay for it.
Thank you for your concise, well-worded answer, TonyTheTGR.
But see, with the advent of this "multi-cart threading", we're no longer limited by a one cart, 8192-token system (generous though it may be). SunSailor is making this RPG in multiple carts. Wizardish is a good example. Eduardolicious fit an entire 3d dungeon (albeit a sparse one) with core RPG mechanices (explore environment, fight monsters, obtain loot, repeat) into about 2000 tokens, if I recall correctly. At this point, in my opinion, if you can't make something larger than an arcade game in the amount of space available to you at this time (again, with the advent of multi-cart threading in mind), than either the notion of it being an "arcade game" is simply wrong, or you need to seriously optimize your code.
However, this is just my opinion, and I am completely willing to listen to anyone who has a different opinion. I would also like to acknowledge the relativity that comes with descriptions like "arcadey". I am fully aware of that, so I would like to define what I feel roughly defines an arcade game before we continue, so as to not cause any terrible confusion.
An arcade game, or a game that I describe as being "arcadey", is a game which has a single mechanic/very limited set of mechanics that is the primary focus of the game (ex. Galaga = shoot aliens, Pac-Man = maneuver maze and collect pellets, etc.). A game of this type also typically has a scoring system, with a "leaderboard", or some equivalent. The game is either very short (10-20 minutes), or goes on literally forever.
Again, please feel free to respond. I love discussing technology and the capabilities of current hardware/software/programmers, as well as the semantics of video games and the constraints set upon them by the tech they run on.
Personally, I enjoy trying to cram as much as possible into a single cart. It makes you think about how you represent your data effectively. Of course, there's nothing wrong with multiple carts, and it opens up a lot of creative options, but I like to keep everything in one place.
For example, here's what I did to compress my background objects in my mining game to minimize code/tokens/sprites at the cost of characters:
They follow a format of (stride/X/Y/index...), with X/Y being in chunks of 8, initially offset by -128 (so that 0x80, the midpoint, is 0)
(Politely hidden so as not to spam the thread with unrelated images)
And that's great! I highly encourage developers on the Pico-8 to utilize any and all tactics to manage data effectively. I would say those methods only further prove the logic behind my opinion that these games will become longer and more complex in the future, as we discover more methods for data compression.
Actually, in the new Tower of Rhavenna, the data is compressed heavily, making up 34% more space on cartridge one and two. The input data is around 40kb and sprites, maps and illustrations are taking something around one complete cartridge alone, including the sound section - which I will need nevertheless. So no chance to bring the game into one cartridge without stripping it essentially. And still, the token count is a seriouse problem.
I think, if you want to make such content rich games, there is no way around than using multiple cartridges and as this is fully supported now, I don't see a reason why not. Again, it is working around another limit and it is a great deal of fun. It resulted in a complete build system, in which I can mix and compress the content of multiple cartridges.
I haven't gone the whole way, what is possible with this approach, but I didn't want to start the project a third time and it seems, that my current approach is sufficient enough to finish the project without major compromises. Only the lighting and line of sight may needed to be dropped, but that wasn't planned in the first place anyway.
My next project, which is already in preproduction, will even go one or two steps further, by dynamically load and replace stored data. Again, it will be a role playing game, but this time more a blend between the original dune and the gold series by SSI. I'm already very excited about this project, although there is still a lot of work to be done with Tower of Rhavenna. It is almost feature complete, but I need to implement and balance the five bosses as well as the random encounters. But all stuff, which shouldn't eat up more tokens from now.
Regarding Nano89, I'll continue development, after I'm through with Tower of Rhavenna. As I won't and can't do a 1:1 port anymore and I don't want to mess up with too many projects in parallel, priority changed a bit here.
Thank you for such a detailed and wonderful response, SunSailor. You are one of my inspirations for pursuing longer games on the Pico-8, and I wish you the best of luck with all these projects you've mentioned. Looking forward to it.
On a side note, would you mind me reviewing (EDIT: Tower of Rhavenna) once you release it?
Your definition of "arcadey" is definitely what I had in mind. But multi-cart threading is news to me. (To be fair, I haven't been here/active very long.) That may be something of a game changer. But I'm no stranger to shortcuting data, that's why I'm doing so much preplanning of my games, and how to manage resources and so forth.
For instance, I'm already planning on scripting the more dynamic mechanics of the games via strings like that above. I'd rather rely on learning more trickery like palette management and that; but I might have to do two-cart stuff - like keeping the core data/maps on one cart, and copying them to the primary play cart as needed.
Where before (in the "big scope" version of Gentroid), I was going to copy up to 5 screens at a time and then script them entirely with content (in a way that's consistent... so the same "scene ID" would script the same elements); and then pair the doorways via tables to the other scene IDs; now I'm just plotting out premade map bits and dynamically linking those instead, and just scripting a few elements into them instead (or changing block/tile types per instance).
For some reason, I don't buy a complete instance of a Zelda or Metroid-style game being fully fleshed in 32 screens without some degree of recursion - which is a normal enough thing, since that's what older developers like Nintendo did anyhow (all item rooms were identical, it just changed the item...and maybe one detail of the secret passage).
I'm also thinking of dynamically changing SFX IDs in the music tab on the fly too - so maybe there's a collection of 60 beats/melodies, but the speed and combination of them could be rearranged on the fly, no? I'm just not 100% on the details of doing so, just yet. I've mostly done content creation in the past, not raw coding.
But to be fair... I AM aiming for a middle ground between these classic designs and a more "arcadey" format, too. I'd like a full session of these experiences to be completeable in a 15-20 minute timespan; and in many cases with a few high score tables and periodic challenge formats (like weekly challenges, or in the case of a DDR project, monthly courses/remixes perhaps, but that's still a little design trickery away).
One of my "dream projects" is to make a game about gaming itself, so that could simply be an afterproduct that uses the multi-cart threading to tie the little projects together into a bigger, cohesive one. That might get a little insane, though. XD And FWIW, that might as well just be "Splore," but with a more gamelike GUI.
The biggest problem for me was and is, that there is no extra space for game meta data. There's space for everything which is needed directly, but not for more abstract things. And yes, the token count is a pain for me as well. What I do with Tower of Rhavenna is some kind of scripting as well - the whole game data is a deserialized tree of tables, which contain interactive "branches", like conditions and action elements. But this leads to a trade off, as the code for these things, deserialization, evaluating the interactive parts and such, cost a lot of tokens as well, further, this leaves the screen drawing parts in the token counting code as well. My approach works well, if you have a lot of game elements, which are similar in their logic (on a pretty abstract way at least), as the code pays off only, if the things are used multiple times.
[Please log in to post a comment]