Hi all, I got inspired to work on a sequel to PICOhaven (tactical card-based RPG-lite) and am about 70% done-- enough that I'm confident I will actually finish and release it (maybe in a few months?)
I wrote music for the original PICOhaven, though I have no particular musical background-- I noodled around on a mini keyboard with minor chords and an arpeggiator to find some ideas I liked, then built a simple version of that in PICO-8, see the cart below.
For the sequel, one idea I had was finding someone who'd be interested in creating a 'remix' or adaptation-- creating their own take on one or both of the theme songs. I'm open-minded about where on the spectrum of "clear remix" to "loosely inspired by" a composition ends up, but I thought the PICOhaven 1 theme songs could provide a useful creative constraint / starting point.
If this sounds interesting, reach out and let's chat, either here in the comments, in DM on the discord, on mastodon, or so on. I'm also very open to critique+tips on the previous music!
This cart contains two theme songs, for reference:
(in case it wasn't clear, this will be another free labor-of-love game, and there is no pay involved :)
I saw kenney.nl released a free CC0 set of 8x8 city-themed tiles in the PICO8 palette, which looked interesting (thank you Kenney!)
Because that set includes more tiles than would fit in a PICO-8 cart, I chose a subset that were most interesting to me and copied them into a PICO-8 cart so I could play around with a few ideas, with some very quick throwaway code to let me move and animate sprites, layer them on top of each other so I could have cars "drive behind" trees, and so on, just to help with prototyping visual ideas.
I saw a few people posting on Mastodon asking if there was a pico8 cart that included these assets, so I figured I'd share this in case it was useful to anyone else for playing around, to save the time of slicing and dicing the tilemap into a PICO8 format. Note: I modified a few of the sprites and added a few other unique combo sprites and accessory sprites for the types of terrain intersections I found myself wanting to draw, but 99% of this is just directly the asset pack from above, packaged into a PICO8 cart.
I joined the itch.io 'Secret Santa Jam' this year, where you get anonymously paired with a random stranger and create a small game for them based on a letter about their interests.
Part of my giftee's prompt was "I like playing games that make me think and involve some kind of strategy e.g. card games like Magic the Gathering [...] I am a huge football fan. I support Manchester United in England and Borussia Dortmund in Germany. I have a rubbish Windows laptop, so any game that can run in browser works best for me.".
I let inspiration guide me from there and here's the small puzzle / tactics game I came up with.
Sadly, there are no sound effects or background music as I ran out of time and wanted to ensure I gave them something playable by the deadline, but maybe I'll come back to it some day...
p.s. I used this free pack of 16x16 sprites as a starting point for the character sprites and animations: https://route1rodent.itch.io/16x16-rpg-character-sprite-sheet, thanks!
Usage (requires keyboard): Type text including control codes (\n, \f, \^, #, and more) live in your terminal and see the result displayed on screen...
You could also just edit a print() statement in a dummy cart and reload... but there's something about being able to edit color/spacing/etc 'live', especially for codes like + and \^v that can take a lot of trial-and-error tweaking.
In the comments below I have a larger utility cart version of this that includes help, save/load/export, and so on. But this first post is trying to pack a subset of that into 560 characters for TweetTweetJam.
p.s. The tweetcart it doesn't quite support all the P8SCII codes (no \a, |, -, and likely more), but the full cart in the comments supports most of them (still not \a).
[updated from WIP post]
I saw the announcement for this week's TweetTweetJam #7 and here's a barely-roguelike in 560 characters.
Feedback, or suggestions for other character shaving welcome!
Note: the game is definitely unfair in that it can generate a level where it's impossible to reach the goal or avoid the dragon (though note the diagonal-move trick above) and you'll have to reload and try again.
If I find time I will come back to it based on @dw817's comment below and figure out if I can cut some functionality (maybe level progression) and add in a way to organically generate a known-solvable map layout.
side note: I had a question about flip() but couldn't reproduce it, so removed it
PICOhaven is a tactical card-based dungeon crawler / light solo RPG for PICO-8, inspired by the board game Gloomhaven. It adopts a modified & simplified version of the mechanics used in that game, to fit within constraints of the PICO-8 environment (code size, resolution, etc), and to streamline solo play.
The story includes 16 playable scenarios (some are optional side quests), 8 levels of ability upgrade choices, and multiple items that also affect gameplay.
Note: This is just a free, solo-fan-made project and has no affiliation with Gloomhaven. If you like this type of game I recommend checking out Gloomhaven (and its official video game adaptation) for a game with a lot of tactical depth from multi-character cooperative play!
Play PICOhaven here: (desktop or mobile)
(for those who like to jump straight in and figure it out as you go)
PICOhaven is a tactical turn-based dungeon crawler / light RPG. You win each scenario and unlock new ones by defeating all enemies in all rooms (unless otherwise specified) before you are exhausted.
PICOhaven is card-based in that at the beginning of each round, you choose two action cards you'll use. These include Movement, Attacks, and other actions:
After you select your cards, enemies will draw random action cards, and you will see an overview of what each character will do that round (the white numbers indicate the initiative: characters with lower numbers will act earlier).
When it is your turn, you get to play these two actions (in either order)... or instead use either of them as a default "move 2" or "attack 2" action if that's more useful.
At the end of the round, you discard those two action cards, and will have to choose different actions the next turn. When you've played through your entire deck, you will automatically 'short rest': you redraw your discard pile but randomly burn one of those cards, meaning you can no longer use it during this scenario. This means you have a finite number of rounds of play before your deck runs out of cards. Some more powerful cards are burned rather than discarded when you play them, so they can only be used once per scenario.
You become exhausted and lose a scenario if you either run out of health (HP), or if you run out of cards in your deck.
At the end of each scenario (success or failure), you return to town and all of your cards, HP, and items are restored, in preparation for your next adventure-- you can try any scenario as many times as needed. The game should automatically save your progress each time you return to town and allow you to return to it later (on the same device/browser-- data is saved locally).
See the next section for some additional details...
You open a door by ending your movement on it. Monsters revealed in the next room will not act until the next round.
So even once you know what two cards you want to play this round, by choosing which card you select first in that 'choose cards' view, you can choose whether you will act earlier or later in the round. When your turn comes in the round, you can still choose to play those cards (or the default move 2 / attack 2 actions) in any order.
A "burn when used" card is only burned if you actually play it. If you select it as one of your two cards for the round, but when your turn comes you use a default Move 2 / Attack 2 action instead of playing it, that card is only discarded, and you'll have another chance to use it the next time you redraw your hand.
You collect treasure or coins by ending the turn on them (or by using certain cards or items). You do not need to collect treasure (and rarely will have enough time to collect all of it without running out of cards and failing a scenario), but it will eventually allow you to buy items that enhance your powers. Note that once you defeat the last enemy in a scenario (or achieve some other special scenario objective) the scenario is over and you return to town, so if you want to pick up treasure you have to do it before completing the scenario... that may not make sense fantasy-dungeon thematically :), but the game's balanced around only being able to afford a few items over the course of the entire campaign.
Enemies do not have modifier decks and always do the damage shown on their card for the round.
If you would take damage that would reduce you to 0hp, you will instead randomly burn a card from your deck to negate that damage, though this reduces the number of rounds you have until you are exhausted by running out of cards. If you have no cards in your hand (i.e. all of them are already discarded or burned) when you are reduced to 0hp, you cannot burn a card and are exhausted as above.
There are a few special conditions that attacks (yours or monsters) can apply, including stun and wound. Stun makes the recipient skip their next turn. Wound makes the recipient lose 1HP at the end of every round (until healed).
Look at upcoming enemy actions for the turn and try to avoid taking unnecessary damage. While you are a warrior, a few mighty blows can bring you to your knees, and healing is in short supply. Winning many scenarios involves more tactical positioning than 'tanking' damage.
Don't be afraid to fail a scenario-- you gain some small amount of XP for the actions you take during a scenario, and you keep any gold you collected even if you fail, and you can try again.
Sometimes it's advantageous to choose a slow initiative, to let yourself react to monster actions or let a monster move closer so you can dart in and attack it without getting counterattacked. Remember that you can use the default Attack 2 / Move 2 actions, so you can select a slow-initiative card such as "Loot 1" as your first card, to use its slow initiative... but then when your turn comes, play it as a Move 2 or Attack 2 instead.
Using too many "burn when used" cards early in the scenario will reduce the number of turns you have until you are exhausted by running out of cards-- you may want to save them for important moments (by using them as Move 2 / Attack 2 defaults the first time through your deck).
Collecting treasure can help you buy items, but is not required-- if you spend too many turns doing that you'll run out of cards before you can complete the scenario...
There are 16 playable scenarios, though about one third of them are optional 'side quests'.
You do not need to use the 'long rest' action-- you will automatically 'short rest' to redraw cards each round. The 'long rest' can be useful when you critically need healing, an item refresh (for a few specific items), or access to a specific card quickly, but it uses up a turn and burns a card so there's a cost to it...
'Long rest' is the one action you can still perform while stunned.
General Experiences + Learning
I've just played around with small games (mostly tweetcarts) in PICO-8 previously, so this was a good opportunity to learn more about the platform and Lua, experiment, and plan something larger out.
I ran into platform limits many times and had to step back and simplify or find a more efficient way to structure code and data to free up "just the 100 more tokens I need"... but I found this resource optimization a fun challenge. And frankly, if I hadn't been working within the PICO-8 resource constraints I might never have released anything-- in the absence of external deadlines it's useful to have some constraints that keep scope in check.
ipairs(), foreach(), and especially P8SCII were new to me and useful for both saving tokens and making it easier to think about code. Amusingly, I implemented my own subset of P8SCII in a mixed-font-and-sprites print routine, but misunderstood its API so I implemented something that behaves differently. To clean up some day...
Using nested calls to split to convert long strings into 2d-4d arrays of key-value game data was essential (I eventually maintained a separate spreadsheet of level/card/enemy/upgrade data that was easier to edit and which compiled all the values together into these long "database strings" which I would copy and paste into the code).
I built a simple "dev support cart" using poke+cstore to move some game data (long story text strings) into unused sprite/sfx cart space, even without enough tokens to include data compression routines or use something like PX9.
This is the first project I didn't develop primarily in the PICO-8 editor-- I used VScode to edit one monolithic .lua file that was #included in a .p8 cart that held all the sprite/map/sfx data. I usually developed with two editor panes open side by side-- one focused on whatever I was working on, and the other to search/scroll through the code for related functions / variables / context.
Debugging unexpected pathfinding behavior (even with the benefit of someone else's A* code, see note below) and figuring out what behavior I wanted when enemies were clustered around chokepoints was delightfully frustrating. This is the one area I ended up building a completely separate test cart I could populate with enemies and obstacles, just to visualize multiple pathfinding approaches.
The source code available in the cart above has comments and whitespace stripped because I was running into Compressed Size limits. I have a fully-commented version of the source code I'll plan to clean up and upload somewhere in the future...
For fun, I recently prototyped a little 'PICO-8 micro-console' (compact enclosure with a Raspberry Pi and square display that boots directly into SPLORE):
It's certainly less practical than commercial off-the-shelf handhelds that support PICO-8 -- it has no battery or keypad (you pair a bluetooth controller to it), but practical wasn't really the goal-- I wanted to build something designed around a high-quality square display.
Internals being tested (Pi Zero W, Pimoroni Hyperpixel 720x720 screen (used pixel-perfect with 5x5 pixels and a minimal 40px black border), USB DAC -> speaker, etc):
I plan to make a smoother white enclosure, this was just a 3D printed first pass with a lot of hand-filing to get everything to fit and figure out hardware. Maybe some day I'll make an extended-case version with a custom PCB to add battery / charging / integrated buttons... but it's nice to call a prototype "done enough to use and share".
I saw someone post a suggestion for SPLORE to add a "play random cart" feature (especially for new game exploration on a handheld without keyboard/web browser, once you get past the list of Featured and New loaded in SPLORE). I liked that idea.
While having that in SPLORE would be cleanest and would stay up to date, I hacked together a quick prototype for myself that loads a random Featured Cart (from a scraped list of the 340 carts on the Featured board as of June 2021) to play around with.
If using it on a handheld it requires an internet connection, of course.
It also adds a Select/Enter menu option to each cart that lets you chain to a new random cart.
[ edit: see follow-up post for updated cart ]
For the newest #tweettweetjam I made a very basic space shooter (layout inspired by Gyruss/Tempest) in <560 characters. It even includes a bit of sound via poke-ing to the sfx memory, since the jam rules say "code only" without separate gfx/sfx assets.
Use ⬅️/➡️ to move, ❎ to fire.
(I may write up a commented / uncompressed version of the code at some point...)
On the last evening of #tweettweetjam I was playing around with free body motion, made a prototype... it evolved into a ~1000 character toy... and I managed to squeeze it down to 560 just before the deadline. The math is buggy when paths get too close to centers, but I sort of like the look so I didn't even try to "fix" it...
Arrow keys move the attractor, 🅾️/Z switches control, ❎/X resizes.
My entry in #TweetTweetJam, in 554 characters.
Cross four levels of increasingly busy traffic, using only the up and down arrow keys!
This was my first time trying a minimal-code jam-- I read various forum tips but I'm sure there's still some compression to be had. Since the jam rules were to use source code only, no spritesheet/map/sfx data, I had the idea of Poke-ing a basic sprite into memory and then using sspr() and palt() to reuse it in different forms... and a little game evolved from that.
Years ago while bored on a train with a deck of cards, I made up this solitaire game (for all I know, it may already exist under another name). So I've turned it into a little Pico-8 cart, my first "finished" game.
(as sounds common, I've started at least 4 other ideas... all in various WIP / playing-around stages, it's just too much fun to try new things...)
Arrange cards to make as many good poker hands as possible. For an extra challenge, play in "Perfectionist" mode where you only score points if you make a pair or better in all 12 hands (across, down, and diagonal), which takes some careful play and a bit of luck.
My personal best score for some time was 44, though I recently managed a 57 when the stars aligned.
Program a tiny virtual console, the "Turtle-2", with increasing levels of capability at your fingertips.
This isn't "done" (there isn't a lot of error checking so there are various ways to make it crash, and I want to add more SFX and animations and maybe figure out custom background music), but it's a playable version of the core ideas. If anyone checks this out I'm curious what you think, whether you find it fun to play around with, and whether you create any interesting designs (share screenshots!)
I'm on the fence about trying to extend it to challenges / puzzles or just leave it as this open sandbox.
I just came across Pico-8, did a few tutorials last weekend, and here's my first cart-- a spaceship flying over an endless 2D parallax scrolling background (with more layers that get added in over time).
The whole experience was a lot of fun for someone who rarely writes software-- just poking around within the tool and trying things out. Thank you to everyone who developed Pico-8 and posted tutorials and tips!
I didn't plan to share anything because this isn't a "game" and I expect the code has all sorts of ugly parts I should clean up. But I saw a talk about how part of the concept is just encouraging sharing in any form. So why not... feedback welcome.
p.s. thanks to @Gruber for the music shared in the Pico-8 Tunes #1 cart.