I'm not finished yet. I posting the game early to let my friends, family, and the community play it.
Any feedback is appreciated!
There's currently no music or title screen.
I have that on my list todo on top of adding more to the game. I plan to be done within the next week.
Recently I've been thinking about those old Gameboy color cartridges that had built-in rumble-packs.
I wanted a rumble-pack for Pico-8, and, by a happy coincidence, I had a bunch of tiny rumble-motors left over from when I was prototyping VR accessories for a former job!
So here's my first draft of PICO-8 Rumble :
Here's a video of it in action. Obviously you can't feel the rumble through a video, but I put a microphone right up against the rumbler. Actually, I think I put it too close, this video is LOUD.
Here's how I did it.
Step Zero : If you've got a pocketCHIP, and especially if you intend to fool around with the GPIO pins, I strongly recommend putting insulating tape over the 5V and BAT pins. If you accidentally connect one of these pins to any of the other pins you could instantly fry your CHIP! They even stay active when the device is off!
Step one : I added header sockets to my PocketCHIP. This is pretty easy if you're even a little competent with a soldering iron. A 6-pin header and a 16-pin header fit nicely and cover the pins of interest. It leaves out the FEL pin, but you'll probably never need that.
Step two : The circuit.
I'm really bad at electronics, so anybody who knows about this stuff please double-check my work here.
The GPIO pins are normally high, so I've designed this circuit to rumble when the pin goes low.
The diode and capacitor are to protect the pocketCHIP from any interference or voltage spikes caused by the motor. I'm not sure if a motor this tiny needs that, but better safe than sorry.
I tested this on a breadboard and it worked great.
Step Three : The casing
I'm also pretty bad at designing objects for 3d printing. But TinkerCAD makes it easy to make something functional, even if it's a bit ugly.
The grey thing is the rumble-motor.
The idea is that you put nuts and bolts through the bolt-holes, and then tighten it onto the top of the PocketCHIP board. The slot in the top is where the wires come out to connect to the pin headers.
Step Four : Assembly
In my mind I was going to lay out all the components neatly. Turns out I didn't leave enough room for that. So I kind of just had to solder them into tangle of components.
Step Five : Programming
One problem here is that only root has access to the GPIO pins. If anyone knows how to change those permissions please tell me. Instead of starting Pico8 from the main menu, you have to start it from the terminal by typing "sudo pico8". It'll ask you for a password. If you don't know it, it's probably "chip".
Activating the rumble-motor through Pico-8 code is surprisingly simple. It was the easiest part of the project.
Here's the code. Just call that update_rumble() function once per frame. Any time RMBL_FRAME is greater than zero it will rumble for that many frames.
One trap is that I've got the rumble connected to what's labeled as "GPIO 1", but Pico-8 sees it as pin 2. :shrug:
Here's a simple test program.
I modified @guerragames's "Pinballvania" to use the rumble. It took me about 60 seconds to make the mod. I copy/pasted the update function, and added a single line to the existing "Screen shake" function, which already was triggered after every hard collision.
I really hope other people build rumblers into handheld pico-8 devices. It'd be great if we could come up with a loose standard for how rumble in Pico games works.
Here's a parts list :
And a case to put it all in. If you've got a 3d printer, you can use the case I designed, but I'll bet you could design a better one.
Play as Ranger the Bounty Hunter and help King Wingarion save the four princesses from the terrible Lord Nimbus!
Ranger is a greedy man... Get the diamonds scattered around the game for some extra difficulty!
LEFT and RIGHT to move
Z to use power/interact
X and/or UP to "advance"
ENTER to pause and access the save game and reset data buttons.
This game started as a gift to my high school physics teacher back in early 2018. Every once in a while I would get in the mood and code a whole bunch of it. And now, it's finally done.
The first "Galaxy Castle" would be the actual physics project that started it all. It's in my WIP page, if you want to play a clunky first attempt at a platformer hahaha.
Hope you enjoy it!
And if you find any bugs, please let me know! Thanks :)
To ease the workflow of developing with p8 file, then saving as PNG for sharing, it would be really useful to have a command-line switch to save as PNG (combined with the positional parameter that loads a cart), for example: pico8 game.p8 -save game.png
This would behave like 'SAVE game.png' in the console, adding the .p8 string in the middle, but not prompting for overwrite confirmation (goal is headless/automatic conversion, like -export — of course errors are possible if the cart doesn’t respect limits).
Rationale: I find myself working with both P8 and PNG carts for the same game/project, using the P8 file as authoritative version (limits don’t prevent saving + compatible with all text tools) and also saving as PNG to see what the label looks like and share it when desired. It is cumbersome to work with the P8, save, save as png, confirm overwrite, then have to remember to load the P8 to avoid that the next save saves PNG then have to overwrite the P8. I would prefer to consider the PNG form a compiled form that I don’t edit, and avoid human mistakes by saving it using a command line or makefile.
Another use case from Sam Hocevar on discord: he wanted to convert P8 to PNG to study the compression algo, and had to resort to export to JS, extract cart data, serialise it, save in blank cart, which is quite convoluted.
I've seen several carts that implement a cool "laser" bullet effect and without seeing the code, wanted to be sure I was able to reproduce an approximation to the effect without botching collision detection.
Thanks to doc_robs for his splendid series of videos where concisely and with patience explains how to properly do hit box collisions on sprites:
In my journey I still need to learn, amongst many other things, to be able to do better sprite animations. But I must admit I love pico-8 for what it is: an amazing platform that favours convention over configuration so one can quickly prototype and publish an idea without getting bogged down on platform or delivery choices.
It's so cool to be able to have an idea and just quickly cook something up. And the amount of published gems from incredibly talented people on splore is at the same time inspiring and humbling.
As a kid, I remember sneaking to my neighbors house to play his Atari. One of the games that I enjoyed was Kaboom!, where a mad bomber man with unknown motivations dropped bombs in sequence that the player had to catch with stacked buckets.
As a homage, I attempted to remake something the likes of it, being the first game I've written in pico-8 that approximates ~somehow~ a completed state. I abandoned the stacked buckets idea and still went for the concept of a madman with obscure motivations that simply drops cherry bombs over a wall to his neighbor. Why? maybe just to be annoying. The neighbor just went for a pail of water as the only thing quickly available.
I've learned a lot making this: screen shaking, particles animation, game states, sprite contouring, text handling, enemy movement. My art + sound skills are pitiful, so please be forgiving in how it looks and sounds.
- parallax backgrounds behind enemy
- save score across plays (hi-score table)
- increasing difficulty
- fancy game over animation
- sound loop
- bonuses? rewards?
This is an example of how to create a "firework" type effect using particles. I have been also fiddling with tweetcarts (carts that fit into a single tweet) so that's why I've been using the reduced syntax, instead of the standard functions. As with everything in gamedev, the more you're able to model a visual effect into its math/symbolic representation teh better you get. It's hard work and a talent, I guess.
This thread isn't the first time I've seen people ask about inserting values into the middle or start of arrays/sequences:
It occurs to me that a lot of carts probably have similar boilerplate code like the ins() function I wrote for that person. I think it would be nice, and better for PICO-8's host-machine performance, if there were a C-side implementation of that insert code, and I think you could do it simply by taking an optional third argument to add(), effectively implementing something like this Lua code on the C side:
function add(t,v,i) i=i or #t+1 -- default to extending the list for j=#t,i,-1 do t[j+1]=t[j] end t[i]=v return v -- return the added value for convenience end
This shouldn't break any existing code, since there hasn't previously been a third arg, and the default value produces the existing behavior.
(Come to think of it, I'm not sure if you have add() on the C side or as hidden Lua. If it's not already on the C side, you might want to put it there, because it happens a lot in carts and doing it through interpreted code is definitely going to slow things down on the host hardware. Same goes for any other oft-called hidden Lua code.)
Walking with rythm
When learning a new language or tool, I tend to create a lot of POCs (proof of concepts) to cement my knowledge. This is just one of them, nested oscillating circles that demonstrate a simple implementation of Lerp (Linear Interpolation).
One of the common mistakes one may make when beginning to use lerp is to forget that the value being affected must be re-calculated as an aggregated or iteration, typically over consecutive game loops. That is, it's effect is dependent of the previous value in the iteration.
I have a cart used as an ongoing reminder alarm, simply showing the previous alarm, the current time, and the next alarm. It runs continuously for very long periods, e.g. weeks. Indeed, this instance has been running since the week 0.2.0i came out.
Today, for the first time I've ever noticed, the display was showing a pattern of corruption. I took a screenshot, but there was no corruption in the screenshot, so I tried saving a gif. I have my gif len set to a couple of minutes, so the result is quite long.
If you pay attention, the gif shows the parts of the pattern changing every second or three:
And yet when I saved a screenshot at the same time, there was no evidence of the corruption:
I assume this is because the PNG is saved from a point in the pipeline that comes before the corruption, while the GIF is saved after the corruption.
This means the cart itself isn't producing the corruption. It's happening somewhere in the frame presentation pipeline.
Not long after I saved these, I tried to save another GIF, and the actual executable crashed.
A basic implementation of Conway's game of life.
- 32x32, 64x64 and 128x128 boards sizes.
- Ability to rewind to state when entering play mode.
- Includes a few structures that can be loaded.
- Ability to set wrap mode. No wrap, horizontal, vertical or full wrap.
Guide your ship and pick up each of the boxes and bring them back to base, while defending yourself. Can you make it through all the levels?
Inspired by the amazing game published by Kingsoft in 1989 on the Amiga with the same name.
I am making a roguelike and i would like to add in procedural generation of rooms. I would have prebuilt rooms in the map editor and when the character goes below, above, left or right of the current room, it would take them to a new room with which that entry was possible. I can do this ok apart from one thing:
How do i store the layout of the rooms once you go into a new room? If it was just left and right i would make a list of the coordinates of the rooms and when the player goes to the right, a new random room would be appended at the end, if it is to the left then at the beginning. Though this doesn't work when i have up and down too. How do i store the coordinates of the rooms that the player has already been in is my question.
I would appreciate some help
I am currently making an infinite dungeon crawler. I have finished he physics engine and basic combat with 3 enemy types. My code is garbage. It has hit 2200 tokens already and so much of the code is probably useless or could be written way better. This is a big ask but i would appreciate if someone could perhaps point out some areas where i could save some big tokens. Little things i will figure our later. And if youre feeling extra kind, my enemies invisibility frames are kinda broken and i cant figure out why, along with the character sometimes randomly falling into the floor because he is more than halfway down so the function which pops him to the next tile puts him on the lower one...