Hi!
I have just started to learn game development. My only programming experience comes from making few simple things in BASIC more than 15 years ago, but when I found PICO-8 (thanks to the C.H.I.P Kickstarter) I felt a nostalgic pull and decided to jump in into this whole gamedev thing.
I have started a blog: Level0GameDeveloper where I document this journey and explain everything what I am doing, so maybe someone like me (who doesn't have an idea where to start with this whole game making thing) will find it helpful and will also give it a try (maybe even with PICO-8?!).
Anyway, I was hoping that you guys could give me some pointers, as many of you are, what I would consider, amazing programmers (I have seen your code!). The great thing about Pico-8 is that I can lookup any source code to the carts posted here and learn from that, but I find myself really struggling understand a lot of it, as I don't know Lua (or programming practices past the basics really). Right now I am working on expanding the pong clone from Pico-8 Zine#1 and it is going alright, but I am afraid that the lack of knowledge of Lua/Pico-8 functions will make me reach a standstill, or I will get frustrated and give up :(
Any advice you would give to a new programmer? Any books or articles you could recommend (especially about Lua, or basics of programming in general)? I have already gone through the zine and manual (however the manual doesn't explain things very well, but it is a good reference) multiple times and I use this BBS daily, so I am looking for any other resources.
So far I am having a blast and I think I can actually do this, but I would love some advice, so I won't give up. Any help would be greatly appreciated.
I spent some time analyzing the palette and came up with some things that I find make it easier to use.
I decided to share it here in case others find it useful as well, so here goes.
First ting I did was map the colourspace. This makes it very easy to find nearby colours when shading or tinting.
The colourspace wraps horizontally thru the spectrum as illustrated by the double width block.
Next I reduced the colourspace to use single pixels instead of clusters. Less accurate but more compact.
Based on this I came up with an comfortable order of the 16 colours (as I found the default colour order not very user friendly). Apart from making it easier to find the right colour quickly, I wanted to make sure it looks pleasing :)
You can use this order regardless of your gfx software fo choice. I made sure the palette works whether it's presented in a single row, 2x8 or 4x4.
An added bonus is that the this order also wraps around nicely, as illustrated by the 'ring' versions on the right.

Hi Everyone,
My name is petri and I'm very enthusiastic about PICO-8 and PocketChip concept.
I decided to learn some coding and try to make my first little game. One of my favorite games from when I was a kid was Boulder Dash so demake for PICO-8 feels just right to do. It's just a mockup for now, but I will try to make it work.
@zep I would like to thank you for creating PICO-8. It's a lot of fun:)

GREG BRING CONTROLLERS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!OK!
I have noticed that whenever PICO-8 is in fullscreen, SDL2 applies a bilinear filter to it, making it blurry. It is more noticeable on Raspberry than it is in Windows (and I think in OSX is where it is the least noticeable). It is there in all platforms nevertheless.
You can see screenshots here. The picture has been reduced, but the effect has been preserved. As you can see, the bottom screenshot (fullscreen) is noticeably blurrier. You can "open image in a new tab" to see the original and the effect more clearly.
Shouldn't it be upscaling using "nearest neighbor" to preserve crisp pixels?
(These two have some additional blur because I have magnified them, but you can appreciate the difference)

May 18 2016
I'm working on my first cart. I hope you'll excuse the crappy graphics!
Move your cross hairs with the arrow keys (0,1,2,3) and fire with Z (4).
The further down you catch a bomb, the more points you will get. And intercepting more than one bomb with the same shot will multiply the score you get.
You can't lose at the moment though :P
There is a massive noise in your precious recording of 4'33" by John Cage in Carnegie Hall. Instead of four and a half minutes of silence -- electronic disaster in your headhones! Get rid of it by applying various filters to reach silence. Each slider controls one filter, which removes one element of noise when set to correct position.
- Not all filters are needed every time.
- Sometimes only one noise element is active.
- Getting rid of one element makes others louder.
LEFT, RIGHT: Choose the filter
UP, DOWN: Move the filter slider
You need sound output to play this minigame.
Warning: Squeaky noises ensue! :-)
Other people are asking for more screen space, I'm asking for the option to have LESS! (and expand to fill the monitor) Why? It can make better use of the Pico-8 map space and improve the level design of your game!
There's a 64x64 game comp with some amazing entries, you can see them here.
https://itch.io/jam/lowrezjam2016
You can see more of the game pictured above here.
https://baku.itch.io/legend-of-xenia
This inspired me - I'm now converting my game to 64x64 as it made me realise I can finally fit the map of the entire game in if I restrict each screen to 64x64 and re-design the gameplay to suit!
This is more in line with the mentality of Pico-8, cut back the game to the core elements. The game is actually better for it - it's more compact, more challenging, more straight to the point, and no dead-space. I don't want to show it here yet because I want to keep it a surprise till there's something decent to show :)
I'm finding when I use "clip" that rather than crop the screen, I wish it could also expand to fill the available view, so I'm not playing the game in a small square in my monitor.
Hopefully this feature wouldn't be too involved to implement?

I'm writing a roguelike! it's not even a game at this point, because all the gamey bits are missing (victory conditions, interesting decisions, etc). So you need stuff(monsters, magic, item, traps). But how do you put stuff in?
For the time being I'm doing it when the room is created. The rooms can vary in size a whole lot by design, but I'm kind of worried about having the same amount of stuff in small and huge rooms.
So I decided for he following algorithm:
1: each room has a 50% chance of having a monster, and if it does try again (and then again, etc)
2: rooms bigger than 20-40 locs should have as many attempts to have monsters (so 2 attempts if >30, 3 if >60, etc)
Here's the code. I understand it's really not much, but it does a neat trick
function stock_room(x,y,x2,y2)
local area = (x2-x)*(y2-y) -- the size of the room
do
if chance(0.5) then -- 50% chance
spawn_monster(x,y,x2,y2)
else
area -= random_in_range(20,40)
end
while area > 0
end
|
Following the announcement of PICO-8 being on the pocketCHIP, someone on the CHIP forums suggested running Voxatron on it. However, I do wonder whether that would work.
Does Voxatron come with an ARM version?
Does it sound feasible to run Voxatron on the CHIP? (other than the ARM-ness of it, of course)

I've done collision detection with object/object and object/tiles. But what is a good way to detect object/shape?
I have a 8x8 player sprite. You can move it, etc. Across the screen is the bad guy and he's shooting at you. If a his bullet hits the player, the player dies.
I want to use circfill() as the enemy bullet rather than a sprite.
I would have the player's _update() cycle check for the collision but what exactly would I check for?
My first thought was to loop through each of the player's hitbox x/y pairs and an use pget() to see if that location has changed to the color of the enemy bullet. But that sounds very expensive to do on every tick.
Is there a better way? I feel like there probably is.
Thoughts and feedback are appreciated.

Hey All
I'm in the process of simplifying the website a little. In particular, I wanted to improve the experience of playing cartridges in threads by removing clutter. They now look more like a page dedicated to the cart:
- The player starts open
- There's a big obvious play button and large thumbnail
- There's no banner at the top of each page
I removed the PLAY buttons from the thread previews, and autoplay, as I think they're no longer needed -- the whole playable region of a cart is now visible without scrolling after opening the cart's thread, and it's more obvious to new visitors what to do next.
There are still a few small things to finish, but let me know what you think of the new layout, and if there's anything that bugs you.

Perhaps this is going to be useful for someone. This is a little keyboard handler I'm using in my code. It extends the functionality of the standard btn(k) function with detection of the onset of the key and its release. Sometimes it's useful to have those two and avoid btnp(k) repetition.
-- is_held(k) is true if the key k is held down
-- is_pressed(k) is true if the key has just been pressed by the user
-- is_released(k) is true if the key has just been released by the user
keys={}
function is_held(k) return band(keys[k], 1) == 1 end
function is_pressed(k) return band(keys[k], 2) == 2 end
function is_released(k) return band(keys[k], 4) == 4 end
function upd_key(k)
if keys[k] == 0 then
if btn(k) then keys[k] = 3 end
elseif keys[k] == 1 then
if btn(k) == false then keys[k] = 4 end
elseif keys[k] == 3 then
if btn(k) then keys[k] = 1
else keys[k] = 4 end
elseif keys[k] == 4 then
if btn(k) then keys[k] = 3
else keys[k] = 0 end
end
end
function init_keys()
for a = 0,5 do keys[a] = 0 end
end
function upd_keys()
for a = 0,5 do upd_key(a) end
end
|

I've bounced around several threads to try and understand how to save game data but it's all kind of scattered, so I'm looking for something more concrete, or an example.
I've read section on memory in the manual and see the cstore() peek() and poke() stuff...but it's just it's just not clicking. I think it's because it's talked about in bytes and addresses, and that's foreign to me. But it seems like saving data between sessions is a do-able thing...I hope...?
I have two things I'm trying to do with save data...
- Save a high score
- Save a boolean to denote whether the player has unlocked a character
I understand that data won't persist between platforms, which is fine. I just want the data to be able to used between game sessions on the same device. So the first time I play the game and get a score, it's saved. I turn off the device/cart. Then I turn it back on and my high score is there.
Any guidance or code snippets are appreciated. This might be a good idea for a Fanzine article too (unless it's already covered and I skimmed over it).
Thanks
I've seen varying techniques for update looping and am looking for insight/feedback on if one is any better than the other in terms of speed/efficiency.
Method #1 I see a lot is a global table of all the actors on the screen. So everything goes here and then the system _update() function is something like this.
actors={}
function _update()
foreach(actors, function(obj)
obj.update()
end
end
|
This method makes sense. Every object then has its own update() method...but that feels kind of inefficient, especially if the update would be the same for like-actors.
Method #2 is grouping like-actors with each group have its own update() method, which is then called in the system update loop.
bullets={}
bullets.actors={}
bullets.update=function()
foreach(bullets.actors, function(obj)
...do stuff to obj...
end
end
badguys={}
badguys.actors={}
badguys.update=function()
foreach(badguys.actors, function(obj)
...do stuff to obj...
end
end
function _update()
bullets.update()
badguys.update()
end
|

This cart is basically a demonstration of a simple tool/function I've made to check/debug the music playing in one of my project, the function need no external dependency and should not clobber your variables as all of them are declared as local. You only need to call the function with the Y position as parameter (positive number are relative to the top of the screen, negative from the bottom) in your update screen function to display a bar with the current status of music playing.
There are four zone, one for each channel, the green/red bubble indicate is the channel is playing or not (green == playing, red, not playing) the number next to the bubble is the pattern used on that channel, and the bar on the bottom is the current position in the pattern.
The function itself:
function debug_music(y)
if y < 0 then
y = 128 - 17 + y
end
rectfill(0, y, 127, y+18, 0)
rect(1, y+1, 125, y+16, 7)
for c=0,3 do
local p = stat(16+c)
local b = stat(20+c)*25 / 32
local col = 8
if p > -1 then
col = 11
end
circfill(9+c*32, 6+y, 2, col)
print(p, 15+c*32, 4+y, 7)
rectfill(3+c*32, 10+y, 27+c*32, 13+y, 6)
if p >= 0 then
rectfill(3+c*32, 10+y, 3+b+c*32, 13+y, 3)
end
end
end
|
This is my first PICO-8 game :D
It was written entirely on a PocketCHIP, and was heavily heavily based on a tutorial found in the first issue of the PICO-8 zine.
It's a single-player PONGish game, the arrow keys can be used interchangeably with the action buttons to move the paddle.
After each 50 points the ball starts going faster! Extra lives are earned per each 100 points.
Good Luck!






17 comments




