Description
You play as a bubble under the ocean that must embark on an epic quest to reach the surface. Avoid obstacles, grab equipment, and reach the surface!
Made for Global Game Jam 2025.


Controls
Tap D-Pad - Add a small impulse to your bubble in the corresponding direction
X - Dash to the left
O - Dash to the right
After dashing, the bubble requires a 2-second cooldown, in which you won't be able to move.
Behind the Scenes
This game was made as a part of the Global Game Jam 2025. The theme was 'Bubble'.
I originally had two ideas. The first idea was a bubble RPG where the bubble only had one HP, however, the idea proved too ambitious to accomplish in two days. The second idea was an endless runner where you have to dodge obstacles on the way to the surface of the ocean.

Since many interesting 3D projects have already been created on Pico-8, it's likely that 3D applications on Picotron will also attract significant interest. I'd like to share some thoughts on my recent experiments:
- Strategy for Textured Triangle Rendering and Userdata
Picotron's userdata is particularly intriguing for someone like me who frequently uses NumPy, even though its XY order is opposite to NumPy’s. This difference has occasionally led to subtle, hard-to-detect bugs in my code. FReDs72 has demonstrated a highly efficient triangle rendering method using userdata. I made some modifications to it, including implementing a fixed command buffer instead of generating a new one each time (as I found that creating large userdata structures is not cheap) and manually unrolling functions and optimizing structures. These changes improved performance by about 20%-30%.

Flappico Birb, for the Pico-8!
I tried my hand at the first of the 20 games challenge, which was to make a flappy bird clone, this took like, 1 1/2 hours to get working, and an additional ~3 1/2 hours to polish (fix up bugs, make pretty, etc.). First time publishing something I've created, please don't look at the code.
DEFAULT CONTROLS
Arrow keys → Movement
z x / c v → O X
My first Game
I have various ideas to make games, but never got around to actually doing anything. Discovering Pico-8 was awesome because its restrictions didn't overwhelm me, and actually helped me to create this project.
In the near future, I would like to make a "Don't touch the spikes" port using Flappico Bird as a base, and after that, I'm confident I will be able to craft my own ideas.
SCREENSHOTS and GIFS







A tiny helicopter like, guide a little bird to the end where something awaits.
CONTROLS: Hold the down arrow to flap, let go to fall, x to restart.
Enjoyed relearning pico8 and excited to make more!
Thank you to thunderjams and cyps for the fun times while making this!





Short game I made for Global Game Jam 2025. This was my first time using Picotron and I had an absolute blast making it!
Let me know if you enjoyed it.

.jpg)






Sokoban with a twist! The box pusher is always in a bubble. Which boxes it can see and push depends on the bubble it is in.
The game still needs polishing, but the basic idea seems sound. Only small puzzles so far, but they are already challenging. Can you solve all eight puzzles?



Sprudel Land
Sprudel Land is a game where you play as a bartender, serving beers to customers. Be quick to survive to the next day and unlock new beers!
Controls
When a new customer arrives, press X at the right time to select the beer they ordered. Next, pour the beer by smashing X as quickly as possible to speed up the process. At the same time, press the up arrow to keep the indicator in the green zone and pour the beer more quickly.
Credits
Thanks to the Global Game Jam and Game Dev Saar for hosting the event
Special thanks to the developers:
- Stardddude
- Elisée
- Loïs




Welcome to the Cozy Winter game!
Controls
to move press the Left, Right, Up and Down keys.
In Cookie Printer, move and press X to shoot!
In Pong, the first player plays with Up and Down, the second player plays with N and M.
In Snow Ball, just use the direction keys.
Credits:
Made by Jachym and Ghazal,
For Cozy Winter Jam 2025
As part of a project I'm working on, I wrote a quick json parser that loads a json file into a picotron table and thought it might be worth sharing.
E.g.
{ "a":{"b":1,"c":-3.5}, "d":["e",true,false] } |
is converted to:
{ a={ b=1, c=-3.5 }, d={"e",true,false} } |
So if you have some data in json format already, it's easy enough to load in. Hopefully a bit useful for storing configurations or data needed by carts outside of the code itself for neatness.
It should follow json specifications (e.g. whitespace outside of strings doesn't matter), and any null values will be handed as picotron's nil - however, because of the ways nils are added to tables, they won't work/appear in the way it does in the json itself.
Also, if the parser runs into any issues, it tries to offer some helpful errors to identify where the problem is.
I've done some light testing of the code, but let me know if you run into any issues with it.
Code is hidden below:
[hidden]
function init_json_reader() J_WHITESPACE = {} J_WHITESPACE[" "]=true J_WHITESPACE[" "]=true J_WHITESPACE[chr(10)]=true J_WHITESPACE[chr(13)]=true J_START_TABLE = "{" J_STOP_TABLE="}" J_START_LIST="[" J_STOP_LIST="]" J_QUOTE="\"" J_COLON=":" J_COMMA="," J_OBJ_STARTS={ n=read_json_null, t=read_json_true, f=read_json_false, } J_OBJ_STARTS[J_QUOTE]=read_json_key_string J_OBJ_STARTS[J_START_TABLE]=read_json_table J_OBJ_STARTS[J_START_LIST]=read_json_list J_OBJ_STARTS["-"]=read_json_number for i = 0,9 do J_OBJ_STARTS[tostr(i)] = read_json_number end json_init = true end function load_json_file(filepath) -- Load and read a json file and return a list or table if not json_init then init_json_reader() end local text = fetch(filepath) assert(text!=nil,"Failed to load json file: "..filepath) return read_json(text) end function read_json(string) if not json_init then init_json_reader() end -- Read a json string and return a list or table. if #string == 0 then return nil end local i=skip_json_whitespace(string,1) if string[i] == J_START_TABLE then return read_json_table(string,i) elseif string[i] == J_START_LIST then return read_json_list(string,i) else assert(false,"Unexpected initial character encountered in json file: "..string[i]) end end function skip_json_whitespace(string,i) -- Skip to the first non-whitespace character from position i while J_WHITESPACE[string[i]] do i+=1 assert(i<=#string,"Unexpectedly hit end of file while skipping whitespace\nin json file") end return i end function read_json_table(string,i) local eot = false local tab = {} local k, v = nil, nil if string[i]==J_START_TABLE then i+=1 end while not eot do k, v, i = read_json_table_entry(string, i) tab[k] = v i = skip_json_whitespace(string,i) if string[i]==J_COMMA then i+=1 elseif string[i]==J_STOP_TABLE then i+=1 eot=true else assert( false, "Unexpected character encounted after reading json entry with\nkey '"..tostr(k).."': "..tostr(string[i]).." " ) end end return tab, i end function read_json_table_entry(string, i) local k, v = nil, nil i = skip_json_whitespace(string,i) k, i = read_json_key_string(string,i) i = skip_json_whitespace(string,i) assert( string[i] == J_COLON, "Expected colon following json key '"..k.."', found: "..string[i] ) i = skip_json_whitespace(string,i+1) assert( J_OBJ_STARTS[string[i]]!=nil, "Unexpected value encounted while reading json entry\n'"..k.."', found: "..string[i] ) v,i=J_OBJ_STARTS[string[i]](string,i) return k, v, i end function read_json_key_string(string,i) assert( string[i]!=J_STOP_TABLE, "Table ended while expecting entry, make sure you don't have a misplaced comma." ) assert( string[i]==J_QUOTE, "Expected json key/string to start with double quote,\ninstead found: "..sub(string,i,i+10).."..." ) i+=1 local s = i while string[i]!=J_QUOTE do i+=1 assert( i<=#string, "Encountered end of json while reading key/string:\n"..sub(string,i,i+10).."..." ) end return sub(string,s,i-1), i+1 end function read_json_list(string, i) local eol = false local lis = {} local value = nil if string[i]==J_START_LIST then i+=1 end while not eol do i = skip_json_whitespace(string,i) assert( string[i]!=J_STOP_LIST, "List ended while expecting entry, make sure you don't have a misplaced comma." ) assert( J_OBJ_STARTS[string[i]]!=nil, "Unexpected value encounted while reading json list,\nfound: "..sub(string,i,i+10).."..." ) value,i=J_OBJ_STARTS[string[i]](string,i) add(lis,value) i = skip_json_whitespace(string,i) if string[i]==J_COMMA then i+=1 elseif string[i]==J_STOP_LIST then i+=1 eol=true else assert( false, "Unexpected character encounted after reading json list entry: "..string[i] ) end end return lis, i end function read_json_null(string,i) assert(sub(string,i,i+3)=="null","Was expecting to read null during json file read, instead\nfound: "..sub(string,i,i+10).."...") i+=4 return nil, i end function read_json_true(string,i) assert(sub(string,i,i+3)=="true","Was expecting to read true during json file read, instead\nfound: "..sub(string,i,i+10).."...") i+=4 return true, i end function read_json_false(string,i) assert(sub(string,i,i+4)=="false","Was expecting to read false during json file read, instead\nfound: "..sub(string,i,i+10).."...") i+=5 return false, i end function read_json_number(string,i) local s = i while not ( J_WHITESPACE[string[i]] or string[i]==J_COMMA or string[i]==J_STOP_TABLE or string[i]==J_STOP_LIST ) do i+=1 assert(i<=#string,"Unexpectedly hit the end of json string while reading a number.") end return tonum(sub(string,s,i-1)), i end |


How to Play
Use the mouse to connect 3 or more adjacent gems of the same color (horizontal and vertical connections only). There are 2 modes, Normal and Timed. In normal mode, the goal is to clear 100 gems to finish the game. In timed mode, the goal is to clear as many gems as possible within 60 seconds.
Scoring
In normal mode, the ending pop-up shows how much time it took to clear 100 gems. In timed mode, the ending pop-up shows how many gems were cleared within 60 seconds. Please share your score screenshot as a comment! :)
Dev Notes
This is my very first game for PICO-8 and my very first project that is open source. Feedback and suggestions about the game and the source code are greatly appreciated as I am eager to grow and learn. Thank you!


.png)

What Is It Like to Be a Bubble?
A meta-interrogation of the physiological patterns, intra-structural semantics, and conscious fabrics of nothingness pockets.
With BULLET HELL ACTIONπ₯π₯π₯
A game by Team Peaceful Bubble for Global Game Jam 2025. Made at the Let's Games! Tokyo site in Tokyo, Japan.
Credits
@acedio - Programming
@douglasdriving - Programming, Writing
@kitasuna - Programming, Level Design
@mabbees - Programming, Music
Shane - Art


Guide your cactus to the skies, being careful to maintain enough water and enough air to stop the bubble bursting.
Uses left and right arrow keys to move (keyboard) or d-pad(controller)
Tap x (keyboard) or a/x (xbox or ps controller) to spend resources to move upwards
Use x (keyboard) or a/x (xbox or ps controller) to start/replay
How high will you get?
Made for Global Game Jam 2025 "Bubble"



π§π·
um joguinho simples de cara ou coroa que eu fiz! o código é bem curto, então se você for brasileiro e estiver começando, espero que isso ajude de alguma forma!
π¨π³
a simple little game of heads or tails i made! the code is very short, so if you're brazilian and just starting out, i hope this somehow helps!
disclaimer: i don't know the rules of language in the forums, but please let me know if I infringed any of them and i'll gladly update my post!
observed: a function definition in which there's a line break between the function
keyword and the name will not be visited when using alt+up and alt+down
expected: it will jump to the line with function
on it
i use this convention to maximize the space i have for writing parameter lists so that i don't have to scroll horizontally, and to me this is the most aesthetically pleasing place to insert a line break