pico-view:
April 2023
Hello Pico-View Reader, this April issue is the fourth in the series. This month has been busy one for the community. Thank you to the writers, contributors, and all supporters, that includes you reader! We thank you from the bottom of our hearts. And with that, have fun adventuring through the pixels and paragraphs of this issue of the Pico-View web-zine!
Authors:
Alanxoc3, Johan Peitz, Rare, Luchak, Marina, LokiStriker, Achie, Alex Wolfe, and Nerdy Teachers
Contributors:
Castpixel, Glimm, Wolfe3D, Marina, NoBad7049, PJBGamer, Street-Monk-1255, Cheez26, Achie72, short_demand, DiscoSoup
Contents:
-Cover Art by castpixel
-The Making of PICODEX - Alanxoc3
-Featured Interview - LokiStriker ft. Marina
-Hellgineers Development Retrospective - Johan Peitz
-Featured Game Review: Tiny Farm - Achie
-Plan Your Game Better Than I Did! - rarelikeaunicorn
-Debugging Motivation - Nerdy Teachers
-Random Reviews - New Release Recommendations
-"Me" vs "Us": The Benefits of Collaboration - Alex Wolfe
-RP-8 Rendering: Laziness is a Virtue - Luchak
-Pixel Art Gallery - Castpixel
-Prototype Party
-Closing Remarks
The Making of PICODEX
by alanxoc3
The original Pokemon games had a file size of about 370 KB. The project I worked on recently is called "Picodex" and it fits the most complex piece of those games, the battle system, into a single 32 KB PICO-8 cartridge. How is this possible? Well, I hope you'll have a better idea of that by the end of this article. Each section below will focus on a specific limitation of PICO-8 and how we can overcome it for Picodex. So let's get started!
Overcoming the Token Limit
Token crunching, limiting feature creep, and writing reusable code are the obvious ways to save on tokens. Let's skip those and cover some less common tricks:
Trick 1. Use "_ENV" in your codebase. Slainte wrote an excellent guide on how to use "_ENV". This strategy saves us hundreds of tokens for Picodex.
Trick 2. Start storing table data in strings. I wrote my own function to do this in Picodex, here is how it works:
zobj"x,29,y,hello,z,#"
-- returns: {x=29, y="hello", z={}}
zobj("x,@,y,@,z,~do_thing", "hello", "pico8")
-- returns: {x="hello", y="pico8", z=_g.do_thing}
For large PICO-8 carts, this function will quickly pay itself off. It literally saves thousands of tokens for Picodex, at the cost of a little extra CPU usage.
Trick 3. If you really need more space, don't waste tokens on function names. You can take advantage of the previous trick and put something like this at the beginning of your program.
setmetatable(_ENV, {__index=zobj("draw_pokemon,@,damage_pokemon,@", function() end, function() end)})
Normally, the overhead for creating a function is 3 tokens, but now we only need 2 tokens per function! This is very unmaintainable after more than a few functions, so you can create a custom preprocessor that will compile your code into this format. Nearly all functions in Picodex are stored like this and it saves about 200 tokens!
Overcoming Resource Limitations
When you play Picodex, you will notice 151 different 6x6 Pokemon sprites as well as 151 different 16x16 Pokemon sprites. That's a lot of sprites! So how does it all fit within a single cartridge?
Well first off, the tiny sprites are actually just a cheap trick. Those are created by scaling down the larger sprites with the builtin "sspr" function.
(Progression of sprites - Each frame represents each git commit)
The larger sprites however span over 3 sprite sheets, which is too much space for cartridge storage even if we overwrite all the sfx/music/map data. The PX9 compression algorithm can save the day here! This is an image compression algorithm specifically designed with PICO-8 in mind. Here is the post all about it if you are unfamiliar.
Using PX9, Picodex stores all the sprites and map data in about 12700 bytes. In this case, PX9 gives us slightly better than a 50% compression ratio and leaves 4000 bytes remaining in cartridge storage that we can use to store arbitrary data later on.
All the sprites are decompressed when the game starts up and stored in PICO-8 memory from 0x8000 to 0xdfff. We can load a section from the decompressed spritesheet memory to the primary spritesheet before using "spr" to draw a sprite. Here is what the function for drawing a Pokemon looks like in Picodex:
g_loaded_row = 0
function draw_pkmn(pkmn_num, x, y)
local row, col = pkmn_num\8, pkmn_num%8
if row ~= g_loaded_row then
g_loaded_row = row
memcpy(0x0000, 0x8000+0x400*row, 0x400)
end
sspr(col*16, 0, 16, 16, x, y)
end
Overcoming the Code Compression Limit
If you find yourself over the code compression limit, you should try using a code minifier.
Initially, I was using my own regex based minifier, which searched for variable names and replaced each one with a new 1-2 character variable name. This script worked well until I was really low on space near the end of development. I then spent a few days integrating "shrinko8" into my workflow.
Shrinko8 is a fantastic minifier for PICO-8.
The biggest advantage shrinko8 has over regex-based minifiers is that it can minify local variables separately from table/global variables. While this sounds like a small thing, it saved me thousands of "compression tokens", which then allowed me to store more data in the code section of the cart. Shrinko8 can even handle cases where you might have variable names within strings, which is simply fantastic.
Fitting all the Pokemon Data
All that's left is cramming miscellaneous Pokemon data into the cartridge. This data includes:
- Pokemon names, trainer names, and move stats
- Pokemon cries
- Pokemon stats
- Trainer data
- Pokemon movesets
Due to the extra compression made available to us by Shrinko8, we can store all the Pokemon and trainer names in the code area, as well as the move stats (power, accuracy, pp). Because the code compression limit tends to rise rapidly as arbitrary numbers are added, we need to store the remaining data in the 4000 bytes of cartridge storage we still have available.
Starting with the cries, each cry in Picodex is only 1 note. 160 notes takes up 5 sfx slots, or 340 bytes, and represents 152 Pokemon (including missingno) as well as 8 extra notes for the remaining sound effects.
Next up, we have to fit the Pokemon stats. Each Pokemon takes up 8 numbers, which represents: evolution, type1, type2, hp, attack, defense, special, and speed. With 152 Pokemon, this ends up being 1216 bytes.
Picodex contains 40 different Pokemon trainers. Each trainer has 6 Pokemon. With 1 byte per Pokemon, the trainer data takes up 240 bytes. Each Pokemon is given the highest level moves they learn naturally, so no need to store any extra data here.
Finally, we can tackle the movesets for each Pokemon. At this point we have about 2200 bytes remaining. Since there are only 165 possible moves in the original Pokemon games, we can represent each move as a single byte. The average number of moves each Pokemon can learn is about 26. Storing all the learnable moves for every Pokemon would take up about 3900 bytes, which is more than what we have available. To bring this size down, we need to find patterns in the data.
Each evolved Pokemon can learn all the moves the previous evolution could learn, so by storing only the new moves an evolved Pokemon can learn, the total number of bytes needed goes down to around 2300. This is slightly over the limit, so there is one other optimization to make. Many Pokemon can learn moves with sequential id numbers. Mew is the best example of this because it can learn all 50 TMs. Instead of storing an extra 50 bytes to represent Mew's moveset, we could just store 3 bytes as a range. For Mew this looks like: "1", "-", "50". Applying move ranges for all the Pokemon saves an extra 250 bytes. Now the moveset data fits within the space constraints, taking around 2050 bytes.
(PICODEX cart with fully compressed data)
And that's it. Now that you know how this game was created, I look forward to playing the data-packed PICO-8 games you create in the future!
- alanxoc3
Featured Interview
with LokiStriker
ft. Marina
Marina: So, what made you wanna make a shmup? Especially one so unique in art-style?
Loki: Well, first, it was the challenge and along side it, the practice.
The idea of stacking additional limitations to PICO-8, such as the two color pallet, the reduced resolution and the one channel for all the sound were alluring as a challenge. What first was going to be just a proof of concept, quickly turned into a game. And so, I decided to take this opportunity to practice new pieces of code I would need to have for when I try to do a bigger, full-fleshed shmup.
I would say that art-style-wise, I was mainly inspired by "Space Impact" for the old Nokia phones (2000's). When I was making the mockup for this game I recalled having played it on my dad's phone. So in a way, the game has a degree of nostalgia to me.
Defender X by LokiStiker
Marina: Ah, interesting. I think one of the appeals of Pico-8 is that it has a certain nostalgia. And you'd be surprised how far this nostalgia can span. Commodore kids to hand-me-down Game Boy kids like myself.
And caravan shooter, I can only think of one other pico-8 caravan shooter off the top of my head... The one game by Alex Roe (@yopenatal). It was epic, but I haven't been able to appreciate it until lately. Funny story, when the game came out I was going to interview the creator, but I over-slept and forgot to reschedule. I can't find the game anywhere online, but yeah it slaps, but it's creation took a long time.
What was the hardest part of making a one-bit game? Design wise, or ect.
Loki: Well, to linger quickly on caravan shooters: the other one I know is Aktane's "Crossgunr DX". I feel this is the first shmup I ever played with a enough of a degree of seriousness to beat the game. Quite in fact, this is a nice segue to your question: Designing a shmup was harder for me.
Not much of a "shmup-player" myself actually, but I've always respected the genre (quite in fact, my first "game" was a simple looking "shmup" in C++). But I lacked a lot of resources in design, such as: scoring systems, the flow of a level, dealing with death, and so many other things. Aktane was instrumental in showing and teaching me a lot of shmup ideas that later on I would implement and have the knowledge to make informed decisions.
But to be more accurate to your question, I don't think I struggled too much with the "1-bit"-ness of the game. Not to say that art comes easy to me, because it doesn't, but I have been doing 1-bit style art for a bit now, mainly as mockups. I'm much comfortable with a "1-bit" or a "2-bit" style than a fully fledged pallet.
In this Old Mockups Image I even have a 32x32 shmup as the original mockup for "Defender X". I think, if we put them side by side, I'm much better with shapes than color in my current ability to make pixel art.
Marina: Woah, nice screen-shots. I'm a big sucker for the red/white/black art style.
Loki: Strong agree, and to that point, "Demon Smash" is also good looking!
Marina: Something Shigeru Miyamoto said once resonated with me... "Donkey Kong Country proves that players will put up with mediocre gameplay as long as the art is good." He later recanted his statement, but I've come to realize it's true with "Demon Smash". Then again there's a few HUGE fans of it, so maybe I'm just salty from development. It's been five months, and I still remember how bad it was. But yeah, I've experimented with the art-style after that game. And I've seen other's utilize it. If I've even barely inspired someone to make a game with it, or a game at all. I'm happy.
But your game is a lot better than Demon Smash. It's really hooking because you want to see the next thing. It's a really fun game-loop overall. I had to quit playing and get back to work after the part where they get behind the ship. And I will admit I did think of how to beat that part while working on something else. So, what was the hardest part of development?
Loki: Well, Im glad you think my game is hooking, that specific section where the player is getting shot from behind was certainly one of the most memorable (to not say aggravating) section to most people, but it is by design. I wanted a moment to stand out a lot to the players, and this had that impact. (Spoilers: Bombs are the solution btw)
To your question: Development-wise, its certainly the second-to-second gameplay of the level. I underestimated how much time I would spend fine tuning each second of gameplay to make the flow the best it could be. "Defender X" has a two minute level, I must have spent 3-4 days in those two minutes alone, grinding one second at a time. Adding something to a new wave, and testing it, both by playing by memory and in an improvised way. Each encounter was developed this way, played in context of the last. It's not until I reach the last two encounters that I decided to boot the program with only those two to test them. This aspect of development really highlighted for me the disproportional amount of "development-to-play" ratio something like that can have. I guess this can be generalized for most games.
To me, "Defender X" was quite fun to develop. Most of the things I wanted I knew I could do, and I didnt even touch the token limit, but I will not lie that as you mention your experience with "Demon Smash", I cant help but recall mine with "Beckon The Hellspawn". I pulled a couple of all-nighters in a self-imposed deadline that took their toil on me, so I understand your experience as well.
Marina: That's funny, maybe white/black/red games have a curse. I'm working on one rn, and I've pulled all-nighters every night for four days now. Hoping to be done by tomorrow. In time for this month's second Mini-Jam. But, you never know, I might sleep through it.
But, yeah, the key to all-nighters is taking naps, and variety in what you're doing. But, with a development so short as this game I guess I started out being motivated by the idea, and now I'm motivated by finishing. How long was the development of this game, "Defender X"?
Loki: As I recall, it was almost two weeks. I think that includes as well the initial mockup. Some of the more technical side of the code was reused from another project (the collision code), but beyond that it was pretty much a smooth development. I guess that is what happens when the goal is clear haha. In this case, the goal was 1 level + 1 boss, powerups and pallets. Later, I decided to implement the unlocks and the other secret content of the game, but this was more of a polishing situation rather than not.
See, at that moment in time, not only was I making a game and close to finishing, it was also LouieChapm's PICO-8 port of Calico and Aktane's Crossgurn Infinite. We were trying to release it along side each other, as a celebration of making games within the server where we hang out (The Lazy Devs Academy Discord Server). So as we were syncing our released dates, I saw what things I could end up adding, extra from the initial goal of the game, but these were more like "stretch goals". I'm pleased to say, that I was able to put them all in. I feel that "Defender X" is a much better game because of them in fact. The unlock/achievement system gives the player goals and rewards that encourage you to get further into the game and it was implemented on the last or second to last day of development.
Marina: Ah. I'm gonna have to try the pre-determined route sometime. Well, thx for the interview.
Loki: Ty as well!
Marina: Noice, and have a good one!
Hellgineers Development Retrospective
by Johan Peitz
What is Hellgineers?
Hellgineers is a bridge building game in the same vein as Poly Bridge and Bridge Constructor. The player has to build bridges that are stable enough to let a number of different vehicles pass. The twist? It takes place in hell and anything can happen.
At the time of writing, Hellgineers has been out in the wild for a little less than a month. Early this year I decided to go full time indie and Hellgineers is the first game to be released from my new studio Apskeppet, and the second game on my Patreon. How did it go? Read on.
Prototyping
Having finished up and released picoSYNTH (a toy modular synth simulator) I felt that the physics simulation I had used for the cables had a lot more to give. Part of the buzz around picoSYNTH was always that it felt good to watch and use, so I wanted to keep some of that for my next game. However, the cables were all passive and didn’t interact with anything, so I needed to develop the engine a bit further.
This led me down a path where I made a prototype that played a bit like Elastomaina, but I always felt that building the levels was more fun than driving on them. One of my prototyping principles is to “follow the fun”, even if it means severe pivoting of the original idea. Applying this turned the prototype upside down and a bridge building game it became.
Development
The main thing I wanted to get through in terms of gameplay was the ability to quickly swap between building and testing. This became the core of the first development and in the finished game I still think it holds up really well. It is maybe not something one thinks of while playing, but being able to quickly get in and out of the action is essential to staying in the flow.
As development progressed, so did my backlog of ideas. But as the list grew, the limited resources of the PICO-8 platform quickly decreased. Not part of the original plan, but in order to wrap the game up and get everything in that I wanted I needed to a bunch of non-vanilla PICO-8 tricks:
- Using the memory usually used for tile maps as additional sprite memory
- An external editor (also made in PICO-8) to build levels
- An external level manager (also made in PICO-8) to handle and tweak level orders and win criteria
- Compressing the source code with an external script to make it fit within the PICO-8 restrictions
In hindsight I’m not sure that all these were needed, and one can argue that they probably didn’t move the needle in terms of sales. But when you’re head down in development it is hard to know what will make an impact and what won't, and at this point it was more important to me to make something as good as possible as opposed to driving revenue.
During this period of the development I tried to be as active as I could and post progress gifs on twitter. This feedback worked great to keep my motivation up but also to start building a bit of hype for the game’s release. It was fairly easy to see what types of posts worked or not and it was thanks to this process that the game found its sarcastic tone and style.
After a good amount of development, all the bits and pieces of the game were completed, but I hadn’t made much content. There were different types of vehicles, a flexible editor, dangers and various contraptions, but due to the game being in constant development all the levels I made had to be remade and I didn’t manage to build up anything I could use. I now faced the dreaded Content Mountain.
The Content Mountain is always my weak spot. I can quickly get systems up and running, make the pixel art I need to showcase the general idea, but I’m also very good at postponing the actual game in favor of making more features. To get the ball rolling I made a spreadsheet and plotted out the available features and combined them in interesting ways. Then I also gave each feature a difficulty rating and had the spreadsheet sort the levels in order of potential difficulty and complexity. It worked surprisingly well. I had to manually rearrange a few things because I wanted a specific pacing of introducing new content, but other than that the initial result still holds. For each level I wrote a single sentence that declared the challenge and goal of the level, and then it was “just” a matter of crunching through as many levels as I could per day.
All in all, since I had most of the physics engine already in place that part of development went quite smooth. Then there are always a ton of things that crop up at the end of development, but part of the fun is figuring out what to fix and what to ignore.
Marketing & Release
In classic stereotypical indie developer style, I didn’t think much about marketing. I do have a sizable following on twitter, so as an excuse I repositioned it as an experiment of “how far can I get without doing proper marketing”. Can’t fail if you don’t even try etc. ?
The week before release I had prepared a number of gifs that showcased different parts of the game. I made an effort to keep the short, to the point, and have something interesting/funny/unexpected at the end to make them shareworthy. As the launch date closed in I kept posting tweets with the gifs to build as much hype as I could. The plan was that if I could get enough sales early on, I would climb the charts on itch and get additional organic views and eventually also sales.
Once the game was out I realized that I had no support from any streamers or youtubers. I’m an old man who’s not up to date with how things actually work these days so a bit too late I reached out to a handful of interested streamers. Given how little and late this happened I’m still happy with the reception and if nothing else it was a learning experience on how and when to approach streamers and what to have prepared in order to make the process smooth for everyone involved.
Reception
So how did it go? In short, I think it went as well as I could have hoped. Given the methods I used I was able to push a lot of eyeballs to the itch page which did generate enough interest to push the game up the charts, making it the second best selling game on the site during the launch week.
A bit after the release I also uploaded a web demo to itch site. Coincidental with this, the game was featured on itch and together I drove a big amount of views per day sending the game to the first place in the New & Popular chart on itch.
Comments on the released game were very favorable and it was clear that the attention to detail I put into the game really harmonized with the community. It has so far received 80 ratings on itch and landed on around 4.8/5. I’m very happy about that!
Conclusion
So with my first game from my new indie dev journey done - what are some key takeaways to think about for future projects?
(1) Finding and following the fun early was pivotal to motivation and prioritizing things. (2) The humor and tone of voice made the game stick out and be memorable. (3) The game cannot be too easy in the beginning. (4) The amount of tricks I had to use to get everything working may not have been worth it. (5) Most of my sales came from traffic I drove from twitter to itch. (6) A web demo helped to get a lot of views and ratings, but it didn’t affect sales. (7) Patreon allowed commissioning music and fonts without risk.
Here at the end of the retrospect I wonder if the game was a good fit for the itch platform. Would be an interesting experiment to publish it on Steam. However, I’m not sure if it will get the initial traction required now that the game is already out and the news value is diminishing. All in all, I had a blast developing the game and sharing the process on social media. I’m really proud of what I managed to put into a single PICO-8 cart and the production values that the game achieved.
Onwards, and upwards!
Special thanks to my patreons for trusting me with money up front; VavMusicMagic for doing the sounds and music; Somepx for making a lovely font that both fit the game and made it stand out; and the PICO-8 community for being super friendly and encouraging.
Featured Game Review
Farming Life in Another Game
by Achie
Do you like fishing in games? Do you like keeping animals? Mining? Farming? Then do I have a game for you and I’m not talking about Minecraft. Grab your hoe, fill your pail and let’s jump into the fieldwork! We're gonna plough all day! Ey! No snickering in the back!
Released earlier this month on the 20th, a developer by the name of lumpycamel posted a little package of so-called "tiny games". Tiny Farm was one of these and managed to grab my attention to try it out! As an avid Minecraft fan, and player of many others like this, it really caters to my taste. So let’s see what it has to offer!
No inherited farm with packages, no crippling debt to pay off, just the lovely frog couple, Frebeca and Frobert, you, and a little farmland. A small animal pen and a little pond is what you get and you are free to roam!
You move around with the ⬅️⬇️⬆️➡️ buttons, generally interact with ❎and handle UI elements, such as opening your bag with 🅾️. So let’s start!
With little money to your name, let’s hit up the pond to grab a few fish and sell them to the froggies! Drop the line and wait for a catch! If you have something on the hook, tap the ❎ and reel in that pesky fish! After you got a few, sell them to Frobert and buy your first seeds!
Now that we have some money, let’s buy some seeds and get to work! You can automatically do needed actions on your soil by ❎ and you can prepare the fields for the seeds. Now if you are ready you can press 🅾️ go the the seed you want to plant, press 🅾️ again and go ham on those fields!
“But hey! You mention you can also mine in this game!” I know, I know. At the dawn of each day magically rocks full of precious ore appear on your land. How did no one notice this yet? Walk up to them, and you can press ❎ to swing the mighty pickaxe! Smash those rocks and gather your share of ores! But what to do with them?
If you walk up to Frobert he can help you with that. If you go to the last page of the shop, you can turn your ores into Ingots with the help of some money, I guess you pay Frobert to forge them by hand, or you can sell them directly. Ingots help you upgrade your tools for better efficiency and money of course lets you expand your farm for more gains!
So let’s go into your house by pressing ❎ and sleep away your boring days when you finished the chores so a new day awaits!
One last thing we are missing are the animals! What is a farm without chickens? Cows? Sheeps? Goats? Okay goats are not necessary, they are the jerks of the animal kingdom, but to be fair they give us cheese so that’s a win I guess? Small price to pay for a Picodon!
So with your money you can grab a few animals from Frebeca! They are pricey, they are needy, but there are no eggs without chickens! Here the chicken comes first for sure! If you purchased a few animals you could see that they are small and they just roam around inside the pen. There is no bucket, no shears, no nests … so how do we grab the spoils? Pretty easy. You need to care for them, so grab your freshly harvested organic grains/legumes/vegetables and feed those poor souls! They will reward you later with their precious eggs, milk, wool and cheese!
And this is mostly the main loop of the game! At some points you will have to get more harvest from your fields so hit up Frobert for some upgrades! Be prepared as they are pricey! First, try to go for the quality of life changes, better hoes, pails, etc. so you can work on your farm better. After that, the good ol’ harvest gain upgrades await your money!
The game will go on and as days will pass, the season will pass too! Each season rewards you with unique seeds only sold in certain seasons. Nice tile and color changes await your little farm and relaxing life! Stock yourself up on beans and chilies in the summer so you can enjoy a warm chili bowl on the cold winter days.
The Pico RPG Forest Tileset gives a nice charming look to the game and the added animals/crops really emphasize that cute yet minimalistic look, very well done! Seasons look unique and the crop rotation, that you are looking foward to, helps them to stand out more!
Sound effects are well made and even though I’m not the biggest fan of the soundtrack, I can acknowledge the cuteness of it!
The game really nails the Tiny theme that it’s going for and has everything you would want in a farming game. Would more things be nice? Yeah sure! Some minor buildings like footpaths, flower pots, fences or even the ability to make your own fields would help the customisation, but this is squeezed inside PICO-8 as it is, it's hard to see all these fitting into one cart. I think lumpycamel nailed the game perfectly and seeing it still being updated from day to day makes me excited to see what's in the future for it!
About the Author
I stream PICO-8 gameplay and PICO-8 game development on Twitch, as well as write detailed dev logs and a game review series called "Pico Shorts".
Thanks for reading!
Plan Your Game Better Than I Did!
by Rarelikeaunicorn
Hiya folks!
I’m rarelikeaunicorn, or just rare, and I recently released Astra And The New Constellation - a PICO-8 game that takes advantage of the multicart export function to let me have 15 levels, each with their own full art and music, as well as a good number of options and recordkeeping.
While Astra was a passion project, it was also a long-term lesson in ways that I could have better planned ahead to define the game’s basic needs, make better use of multicart save/load, and organize my data structures.
If you’re thinking about building a bigger project in Pico-8, here are some of the tips I wished I’d had a better grasp of before I started building Astra:
Make a visual map of your data structures!
Even in a single-cart game, you’ll want to plan out the relationship for different states of your game and how you’ll use your cartdata indices. This can be as simple as: your Title Screen goes to your Gameplay Screen, and then back to the Title Screen (via cart reset or another trigger), but it’s still useful to map out even that in case you come back later and decide to add more.
As important as the states themselves are how you build the transitions. Need an options menu or a level select on that Title Screen cart as a submenu? Want to skip your fancy anime intro cutscene when going back to the Title Screen from a finished playthrough? Draw it out to see what transitions you need, where they start and end, and go from there. In single-cart games you can manage a lot of this with just a few booleans; for Astra and its multicart structure, I dedicated a cartdata index to tell the game which state a cart should be loaded into based on the state it’s being loaded from.
A partial structure map for Astra, which I should have made much earlier on.
You’ll have 64 cartdata indices for storing integers across play sessions (and across multiple carts in a multicart project), which will be sufficient for a lot of your needs: each option that a player might toggle, like turning the music on and off, could be handled with a single data index that gets checked when needed, most often when loading the next cart or a new playstate.
Menus
Custom Options
If you’ve got complex needs that don’t smoothly fit into 64 integers, you can still make it work! One option is to store multiple binary-choice options settings in the same integer by having their checks care about different elements of the integer - like one option checking whether the value is even or odd, and the other checking whether the value is greater or less than 5. I’m very confident there are more token-and-processing-efficient methods than the ones I used for Astra, but I went with the solutions that made sense to me and my skill level. Which is its own lesson, honestly - I made a conscious decision to not worry too much about how my solutions to code issues would look on paper, especially when I knew that taking the time to do something in a cleaner or more “correct” way might slow down my progress so much that I lost all my momentum or motivation.
Plan your scope creep!
After you’ve identified all the necessary components of your project, you can start to think about what else could round it out later in development. When you want to add that extra bit of polish or a new feature, take a few things into consideration first:
How many tokens (or sprites, or sfx patterns) will I need for the core components of the game that need to appear in every gameplay cart? Am I already so close to the limits that there’s no way I could sneak something else in?
(1) How many of my remaining tokens does this feature (or visual effect, or et cetera) cost me? Is the cost too high for the result I’d get from adding this?
(2) Will this still work if I have to simplify it? If the cost ends up being higher than expected, will I have to cut the feature entirely?
(3) Are there any “domino effects” I’d need to consider if I add this later? Will I have to go back and change other logic to account for the feature, or will it be fully self-contained if implemented?
(4) Will I have the ability to fix any related bugs if they arise? Is the feature so complicated or token-intensive that it may have to get removed after release if there are major issues?
If you don’t feel super confident after considering these questions, it might be worth putting the idea aside or only going back to it once you have more of the core work completed. Scope creep often gets a bad wrap, and rightly so, but it’s always good to consider what else you could do to make the game you want to make - as long as you’re willing to edit those ideas in the process.
Game development is awesome, and awful, and complicated, and frustrating, and exciting. It’s… a lot of things, honestly. But planning ahead can really make a difference in not only how much time you have to spend going back and redoing things, but also in whether the project gets finished at all. Find the types of planning and structure that fit you as a person, the needs of your project, and your timeline - preferably in advance, and not halfway through a three-year project!
- @rare
Debugging Motivation
by NerdyTeachers
Game development can be a fulfilling and exciting hobby, but it's not without its challenges. One of the biggest obstacles game developers can face is a sudden lack of motivation. Low motivation is a common topic discussed in the community and can impact the overall satisfaction of a developer within the hobby. For new developers, it can even push them away from the hobby altogether. This month, we had an ongoing discussion on the topic that stemmed from an interesting idea.
A fellow PICO-8 developer, luchak, mentioned his experience stuggling with motivation while hiking, "If my mood suddenly crashes, or I suddenly slow way down, that's the time to ask: 'what do I really want right now?'"
He continued with some examples:
"Water or some other liquid? That's easy, I'm thirsty. Drink water."
"Candy, fruit, sweet things? Probably need sugar, go for sports drink / dried fruit / etc."
"Ice cream? I just need calories, see if I have nuts or chocolate."
"Fries? Oh, I don't need water, I need salt."
Hearing him describe how he listens to his body's cravings and then analyzes what the true problem is in order to find a healthy solution sounded a lot like the logic we go through when debugging a coding error. Often times, the error message we get doesn't actually point to the true cause of the problem, but it does give a hint for us to track down the true problem, and once that is found we can apply the best solution.
So this got me to ask the question: What if we approach motivational problems with the same debugging logic that we use as programmers?
The discussion continued with many of us sharing our experiences. We described our symptoms, causes, and the solutions that worked for us. We did this with the goal of attempting to compile a list of "error messages" (how we feel when unmotivated), possible root causes related to those "errors", and possible solutions that address the root causes.
So let's try it! Let's apply our analytical skills of debugging code to our own motivation problems.
(Disclaimer time! We are simply fellow game developers exploring this topic from first and second hand experiences, and we provide our perspective and advice here as educational and entertaining, not as professional opinions on mental health.)
Debugging Approach:
Step 1: Read the Error Message
As a game developer, it's important to be aware of the symptoms of low motivation so you can take action to address the problem. Try to identify the specific feelings you are having. Some common signs of low motivation include procrastination, difficulty concentrating, feeling apathetic, having a desire to quit, or a sudden decrease of the excitement and joy that you once had.
Step 2: Identify the Real Bug
Once you've recognized the feeling of low motivation in any of its many forms, don't ignore it. Instead, take a closer look and try to identify the root cause of the problem. Take a moment to reflect on your own situation and try to pinpoint what happened before your mood changed.
Step 3: Squash that Bug!
Once you've identified the possible root cause of your low motivation, it's time to take action to improve it. Sometimes there are multiple issues happening at the same time and just like code, it might take multiple solutions to no longer get any "motivational errors".
With those steps for debugging motivation in mind, we wrote this reference guide to help others climb out of low motivation faster, and stay motivated longer. Try this out yourself, and share it with others when a fellow dev is feeling unmotivated.
We decided to make this a separate page so that it is easily accessible outside of the zine and can be further grown and built upon. So we happily welcome more discussions on the topic of motivation. Share your experiences with us and let us know if there is something you think should be added there.
Each of us are more strongly motivated by certain things, and so too are we uniquely demotivated by certain things. So I believe it is important for us to grow stronger by reflecting on what motivates and demotivates us in order to discover what solutions work best for us personally.
Low motivation can be a serious issue for game developers, and we want you to know that you are not alone in experiencing it. I believe that you can regain your motivation and continue on your game dev journey with excitement and joy. Remember, it may take some trial and error to find the strategies that work best for you, but I hope our advice can lend some guidance and inspiration.
Random Reviews
Game Recommendations on
New Releases: April 2023
Hit8ox
"Hit8ox pushes the limits of what can fit in a single pico-8 cart. Although a slow game, it provides some fun as a 3D fighting game. When dealing with technological marvels like this, its existence justifies itself."
-Marina
"I don't think I would believe this game would be possible in PICO-8 if I hadn't seen it myself, but this boundary pushing game is a perfect illustration of this tiny console's true potential! It's a simple fighting game on the surface, but it manages to be an amazing technical achievement in its own right! It definitely hits all of the boxes!"
-PJBGamer
Juggle Struggle
"Juggle Struggle shuttles subtle hurdles via addled paddles."
-Wolfe3D
Minotaur
"Minotaur is a challenging dungeon crawler/hack-and-slash style game. King Minos has thrown you and your friends in the dungeon. It is up to you and your survival skills to rescue them. I like the looks and the controls work great. It can be challenging until you get a sword upgrade but this game has good replayability. Highly recommended."
-NoBad7049
Moon Patrol
"Moon Patrol is a beautifully polished, retro arcade blast, that just makes you want to have one more go every time you fail. Wonderful feel to the moon rover, especially the way the wheels bounce over the ground."
-Street-Monk-1255
Pico Valley
"This Stardew Valley demake brings you back to the lovable rural Pelican Town but in ultra low resolution. Being a big fan of the original myself, it is a joy to explore the familiar roads, visit the townsfolk and do a surprising amount of fishing, mining, and farming. It does a great job of packing the Stardew Valley feel into a tiny form factor."
-Nerdy Teacher J
Cyber Tinker
"The moment I laid eyes on this game and solved the first level, I got all excited to play! The visuals are so cool, I love it. It looked simple at first... It is simple, but it's also a bit challenging, and I had to think differently to learn how to solve the puzzles. However, once I did, it was sooooo satisfying!! Totes recommend it if you just wanna chill and have fun :)"
-Glimm
SokoVirus
"SokoVirus is a pretty straightforward sokoban puzzle game with a cyberpunk theme. I do recommend it despite being stuck on one level. I have yet to finish it, but I can tell that it's a great game that requires a good amount of thinking before taking your next step, much like other sokoban games of the past, especially when you want the best score, y'know? I gave this game a chance and so should you. Good luck."
-Cheez26
Microbot
"MicroBot captures the huge genre of metrioidvanias in a micro package. Vibrant art and cool soundtrack surrounds you on your journey to finding O2 on this desolate yet very hazardous land. Be careful though as one wrong step could end (and start anew) it all!"
-Achie72
Neon Saucer
"Neon Saucer combines the color-matching mechanics of Ikaruga with the high-speed aesthetics of a 90's cyberpunk anime. Delightfully frustrating and compellingly replayable, Neon Saucer's simplicity and difficulty make it worth hours of replay."
-DiscoSoup
Froggo: Hop Across The Seasons
"Froggo: Hop Across Seasons is a charming platformer where you use a frog's hop and tongue to hop your way across 8 different season-themed levels. The cute characters, environments, and music kept me going through its precise jumps and clever puzzles. If you're looking for a short platformer that makes full use of its mechanics, Froggo Hop Across Seasons has you covered!"
-short_demand
"Me" vs "us":
The benefits of Collaboration
The benefits of Collaboration
by Alex Wolfe
I've been developing a fan game based on Teenage Mutant Ninja Turtles for about a year. This is the story of how I went from a single developer to a collaborator, and how my game became exponentially better as a result.
In the early Spring of 2022, I wanted to try to create a PICO-8 adaptation of Samurai Warrior: The Battles of Usagi Yojimbo, originally for Commodore 64; a game which features a semi-related though wholly distinct character Usagi Yojimbo. I wanted to see if I could update the gameplay to be a more fluid action/storytelling system with 3 dimensional movement, like the one seen in the excellent Trek to Yomi.
I first decided to try to make a character that could move around the screen so that I could test things like walks, runs, and jumps. I drew a blue stick figure character and began to work out a basic engine.
Then, I used the same character sprite as an enemy npc and palette swapped it to red. As I began to fill my screen with blue and red characters, I decided to add some more color variants to the enemies and made a version using green.
My mouth dropped open. I slowly drew a blue mask around its eyes. That was the moment I realized that Samurai Warrior would have to wait.
I posted some gifs of what I was working on to Twitter and received very positive feedback so I decided to press forward with a PICO-8 Ninja Turtles action game.
As with most PICO-8 devs, I was a one person development team. However, I did reach out to a very busy childhood friend who is a professional musician/composer for help. We would meet on Zoom every few weeks and I would show him what I had been working on and he would show me little ways we could improve it.
Around this time, a game called Downstream Dream had just been released. Seeing it in action was nothing short of remarkable. The game featured impressive scrolling backgrounds and highly appealing character sprites. The amount of sprite art on screen was something I had not realized was possible within the limits of the engine. The developer, RidgeK, also wrote an amazing Twitter thread here explaining the methods required to shuffle compressed artwork resulting in a game that looked impossibly good for PICO-8. It was hugely inspirational as well as informative.
Then as I began posting small WIP versions and gifs, RidgeK commented positively on my work! I thanked him for his game and his hugely informative thread, and going forward I occasionally asked for his advice. He was always very approachable and kind, and I'm sure now, looking back, that I would never have gotten very far without him.
Roughly eight months later, in December, I released what was to be my final single-cart version of Shredder's Prevenge.
The demo was admittedly slow and clunky, but I loved it. I decided that I wanted to continue developing it until it was actually fun, or the copyright holders shut me down.
I decided to try using a multi-cart system, and to see just how far I could push my gameplay if I had an entire cart's worth of tokens for my combat, instead of cramming it in with the menu and animated title.
The demo which I had just released represented a lot of growth for me, but it also began to reveal the limits of my capabilities. I had enjoyed writing the music, but in honesty my compositions always sounded amateurish and tinny to me. My childhood friend had done a lot to elevate the work I had done, but I didn't want elevated bad music, I wanted good music!
Around that time, RidgeK started releasing PICO-8 music carts which were just as, if not more, impressive as his Downstream Dream graphics had been a year before. His synthesized drum noises carry a weight and tone that I did not think was possible within the limitations of the sfx editor, and the compositions themselves were somehow entirely original and unique while being instantly relatable.
I wanted that kind of sound in my game, and I realized it was never going to happen without his help. I was worried he would politely reject me but ultimately I decided to reach out and ask if he was interested in writing a track for one of the levels.
To my surprise, he replied that he had been considering reaching out to me with the same offer to write music for my game but was worried I would be offended at the suggestion because I had been writing my own music!
He asked how many tracks I wanted him to write, and I jokingly replied that he could score the entire game as far as I was concerned. And he then agreed to SCORE MY ENTIRE GAME. I'm still reeling from that conversation.
This past April, less than 4 months after agreeing to work with me, I posted a new demo with 5 incredible RidgeK tracks attached, and this summer I plan to release the final version. Along the way, he has also helped me to refine my gameplay, my coding, my artwork, and the very spirit of my game.
What I have learned is this: We are all flawed, imperfect beings. Like PICO-8 itself, we are bound by internal limitations that prevent us from achieving all that we desire.
But unlike PICO-8 those limits are flexible, and changing, and unique to the person. And those problems which seem insurmountable to you go unnoticed by others who fly past them with ease. And your own capabilities may seem wondrous and impossible to others who do not share your own talents.
I should note that before asking for help, it's important to try to take things as far as you can on your own first. People are drawn to invest energy and time into projects they can believe in, and a half-baked project idea with no functioning assets or code will often leave you ignored by the community at best.
But if you have something tangible, perhaps some artwork, some music, a demo, and you are feeling the limits of your own capabilities, perhaps it is time to reach out to collaborate. Pico 8 has an incredible scene of friendly developers ranging from seasoned pros to hobbyists and students.
Additionally it is important to build relationships. If there is a developer you admire, comment on their work and let them know. You may be surprised to find that they will appreciate small gestures like that more than you had realized, and that they will remember your name and think fondly of you when they encounter you again.
People are simply more likely to help you with your projects if they already like you and have seen you put in effort. There is no shortcut on this path, so start today.
You can play the latest version of Teenage Mutant Ninja Turtles in Shredder’s Prevenge and if you are curious about earlier incarnations, you can find several WIP versions here.
- Alex Wolfe
RP-8 Rendering:
Laziness is a Virtue
Laziness is a Virtue
by luchak
RP-8 is a synthesizer and miniature music studio for PICO-8. It generates and mixes 8 channels of audio in real time, along with 6 different effects for modifying their sound. It also offers sequencing and realtime control over sound design. This article discusses how RP-8 uses laziness to fit both audio synthesis and UI rendering into a limited CPU budget.
The Problem
Here's what RP-8's UI looks like in action:
Since synths are all about sound, you can also hear RP-8 play a song here.
Without audio, drawing this UI would be straightforward. There's no 3D, no complex physics, just a bunch of sprites and text in a rough grid layout. Unfortunately, rendering audio requires a lot of computation, taking roughly 75-80% of PICO-8's CPU depending on exactly which features are in use. On top of that, there are a lot of controls to draw, nearly 200. Just the spr
, rectfill
, and print
calls required to draw the basic UI elements take over 25% CPU, which together with the cost of audio generation already puts us over our CPU budget. And that's without even taking any other visual elements or overhead into account.
Exceeding the CPU budget is bad enough for graphics, causing slowdowns and stuttering, but it's catastrophic for audio, causing crackling and popping. We need to make the UI more efficient, which means either drawing simpler things or drawing less. The individual graphical elements are already simple, so RP-8 focuses on drawing less.
Lazy Widgets
The most important rendering principle RP-8 uses is: on each frame, only draw the parts of the UI that have changed. To achieve this, RP-8 uses a technique I'll call lazy widgets.
What's a widget?
RP-8's UI is made up of widgets. These are the individual buttons, knobs, note tiles, and numeric displays that the user interacts with - everything on the screen except for static, non-interactive labels and decoration. For example, in the image below, each button, knob, etc. is a different widget. Only the solid background and the knob labels are not widgets:
When RP-8 starts, it first draws all static UI elements using a few different map
calls, then it creates all the widgets that will ever be displayed on screen at runtime. At creation time, each widget registers a set of properties that define its behavior, including a bounding rectangle, a label tooltip, callbacks for handling various input gestures, and a display callback, which fetches the widget's current display state.
What makes these widgets lazy?
RP-8 almost never clears the screen. Instead, on each frame, it asks each widget for its current state, and only draws those widgets that have changed.
Widget display callbacks do not call any rendering functions. Instead, each callback returns a number or string describing how its widget should be drawn at the current frame:
- A number
x
invokesspr( x, widget_x, widget_y )
- A string
s
must be formatted astext, fg_color, bg_color [,x_offset]
, and will call bothrectfill
andprint
to clear the widget's bounding rectangle and draw the corresponding text in the correct colors, with an optional pixel offset in thex
direction.
Since numbers and strings can quickly be checked for equality, RP-8 can store the last drawn state of each widget, and only draw widgets whose current state differs from the stored state. This logic greatly cuts down the total number of widgets drawn. It also happens to be fairly token-efficient, since widget rendering logic is standardized and centralized.
Does laziness pay?
Yes! With the above approach, since we draw many fewer widgets on each frame, the cost of drawing the widgets in the RP-8 UI goes from 25% CPU (conservative estimate) to about 7% CPU (actual value). This value can go a little higher at bar or note boundaries, since many UI elements may change simultaneously when new bar or note data is loaded, but these spikes are predictable, so the audio driver code can compensate by computing slightly fewer audio samples on those frames.
Is Laziness for Me?
In general, it's always good to look for opportunities to be lazy. If there's a value you don't need to compute, or a sprite you don't have to draw, it can often be a good idea to avoid the unnecessary work. Some of the other ideas here, like defining string or numeric states for entities to speed up value equality checks, might also be useful.
But is this particular lazy widget technique for you? It might not be. Lazy widgets are most appropriate when your app or game has a large number of graphical elements that do not move relative to each other, do not obscure each other, and where most elements do not change on most frames. (If every RP-8 widget changed on every frame, this technique would increase rendering CPU usage to about 45%.)
Most PICO-8 games don't fit this description. However, if you are building UI-rich tools, a simulator game with a lot of control panels, or something else with a lot of little fiddly things lined up on screen, then consider being lazy!
One extension to consider would be implementing more flexible rendering by allowing widgets to define their own render state value formats, then invoking widget-specific render code when those values change. RP-8 does not do this since its widgets are simple and the additional logic could harbor subtle bugs, but this is an option for more graphically adventurous interfaces.
Wrapping Up
RP-8 needs to draw a complex, dynamic UI on a limited CPU budget. Fortunately, since most of the screen stays the same from frame to frame, on any given frame we can limit CPU usage by being lazy and avoiding drawing the unchanged parts of the screen. There are some additional complications not discussed here, like how to handle the mouse pointer and other overlays - perhaps those will appear in a future article.
If you'd like to check out RP-8 and see this system in action, you can find it on Itch or on the Lexaloffle BBS.
- @luchak
Pixel Art Gallery
Artist Spotlight: Castpixel
Christina Antoinette Neofotistou (aka castpixel) has been a professional illustrator for over two decades. She began making digital art on the Commodore 128, using the PETSCII character set and still enjoys pushing pixels to the limit with very small resolutions. She has worked for many big name clients such as Mojang, WB, Hasbro, SEGA, IDW, and Unity.
If you have been a long time member of the PICO-8 community, you may already know Castpixel for her collaborations directly with Zep himself going back to the earliest days of PICO-8 in 2015! Orbys and Squiddy for example. We are also very honored to have her bless this month's Pico-View by illustrating the cover art!
You can find and follow Castpixel on Twitter as @castpixel and play her games on itch at castpixel.itch.io.
Prototype Party
Each month, this section of Pico-View will bring you a prototype with a focus on a unique mechanic or style. You can take the challenge of putting your own spin on this prototype. Feel free to take the code from here and use it however you want!
This month's prototype is named "Neon Signs". It builds off of last month's challenge by using that neon_spr
function to draw the sprites in this game.
The neon lights works well for this month's challenge: Create a game using the classic Game & Watch liquid crystal display style. If you've ever played those old handhelds like Game & Watch, you'll know that you can see a faint image of where all the sprites are on the screen and the illusion of animation happens when these sprites light up.
We have done something similar here, by drawing the neon signs as dark blue when they are not lit up, and movement is shown by turning fixed position sprites on and off.
We hope this inspires some creative new games, so take this mechanic and see what you can do! Try it out right here!
We challenge you!
Take this prototype as a jump-off point to practice your skills, and add your own flavor to it. The only requirement is to keep the visual style of Game & Watch games!
How to Share
You can post your spin-off on the BBS, tweet it with the hashtag "#picoview", and join our Discord community if you have questions or want to share your progress. Here is the game cart if you want to see how we made it!
Closing Remarks
Thank you for reading the April issue of the Pico-View web-zine! We hope you enjoyed all of the articles this month. Here are the folks who helped piece the zine together one pixel at a time...
-Castpixel - Cover Art and Pixel Art Gallery
-Alanxoc3 - Article Writing
-Johan Peitz - Article Writing
-Rarelikeaunicorn - Article Writing
-Achie - Game Reviewer & Article Writing
-LokiStriker - Interviewee
-Marina - Interviewer & Zine-founder
-Alex Wolfe - Article Writer
-Luchak - Article Writer
-Glimm, Wolfe3D, Marina, NoBad7049, PJBGamer, Street-Monk-1255, Cheez26, Achie72, Nerdy Teacher J, short_demand, DiscoSoup - Random Reviewers
-NerdyTeachers - Zine-Coordinator, Editor, and Article Writing
Thanks to all the authors, contributors, and readers for supporting our Pico-8 zine! If anyone would like to write an article, share pixel art, or help with anything contact @Marina Makes or @NerdyTeachers on twitter or Discord.
-Nerdy Teachers
6487
30 Apr 2023