

Sourcecode + Stand-alone-versions:
https://github.com/GPIforGit/rockfall/releases/

Rockfall is my interpretation of Boulder Dash from 1984. You play Rockford, who tunnels through dirt to collect gems. Gems and rocks are fixed until the dirt under them is removed, then they fall and become a hazard.
Your goal is to collect as many gems as possible and leave the cave through the exit. The exit only opens once you've collected enough gems. After completing a cave you get points depending on how many gems you collected and how much time is left. Every 500 points you get an extra life.
Every five caves, you have a chance to earn an extra life in the intermissions. If you fail, you don't lose a life.


I work at the moment on a jump'n'run-Game. One of my goals are to have a better camera-control than simple center the player in the middle, the camera should "look ahead".
Don't expect any game here, it is more a "prove of concept"-demo.
Control:
X for jump
o for grabing things
down+jump - fall down on "half-tiles"
stand+up - look up
stand+down - look down.
there is a coyote-time, that you can jump for a short time, when you run over a "cliff".
up - run on "half-tiles-slopes" (the green on the right side, behind the "secret"-Wall
.jpg)

it is not possible to delete the high-memory with one memset-command
poke(0x8000,1) poke(0xffff,1) ?peek(0x8000)--1 ?peek(0xffff)--1 memset(0x8000,2,0x8000) ?peek(0x8000)-- still 1 / should 2 ?peek(0xffff)-- still 1 / should 2 memset(0x8000,2,0x7fff) -- ?peek(0x8000)--2 ?peek(0xffff)--1 |
the first memset is ignored, because 0x8000 is -1





Puzzle Duck




A simple Puzzle Bobble / Bust-a-Move - Clone.
from URL Wikipedia:
Puzzle Bobble,[b] internationally known as Bust-A-Move, is a 1994 tile-matching puzzle arcade game developed and published by Taito.
At the start of each round, the rectangular playing arena contains a prearranged pattern of colored "bubbles". At the bottom of the screen, the player controls a device called a "pointer", which aims and fires bubbles up the screen. The color of bubbles fired is randomly generated and chosen from the colors of bubbles still left on the screen.


according to the manual:
A += 2 -- EQUIVALENT TO: A = A + 2 // note that the LHS appears twice, so for TBL[FN()]+=1, FN() will be called twice. |
ok, let's test it:
function fn() print("in function") return 1 end f={ 10 } print("f[1] is "..f[1]) f[fn()]+=1 print("f[1] is "..f[1]) |
the function fn is only called once!


A very simple game. Your goal is to destroy all blocks. The problem: You can only move the ball horizontally, the ball moves up and down automatically.
Crillion is an adaptation of the game of the same name on the C64. This release contains the levels of the three official Crillion releases: Crillion, Crillion '93 (hard), Crillion II (very hard). In addition, the levels of Brainion are included, which are designed more than puzzles. And "Junior" from Crillion Junior - a very easy level set.
Rules
Block
![]() |
[64x8] |





SDK-Units of consoles have normally more memory.
This can be useful during developing - simple try something without care about limits. Or store additional debug information.
it would be nice, if pico-8 would emulate this.
This can be done very simple:
The project must be saved as ".p8"-utf8-file.
When the project hit the limit of characters, compressed size and token it will display the known warning with a little addition: "Ignore? (Project can't be exported!) (y/n):" - when you hit y - it will start anyway. Save as .p8 is always possible, since there are no limits.
Of course the export to bin, web, rom, png or whatever is not possible. also the cli-command "-run" should not work on this oversized p8.
This would be usfull, when you want to check, if something work. Or when you developed a tool / level editor for a game, which you don't want to share.
additional it would be nice to have an debug - enddebug - command
function test(a,b) debug if not a or not b then print("this should not happen! Got nils!") end enddebug ... end |





A very simple font. A little bit bigger than the original, but better readable.
the UTF Latin-1-Suppliment-Characters are included instead the Japanese characters.
type
load "#variablefont" |
in pico-8 to load the cartridge.
Created with jaP8e - https://www.lexaloffle.com/bbs/?tid=49307



I tried to decompress the source code of my dithering-demo:
https://www.lexaloffle.com/bbs/?tid=49309
and my code failed.
First i thought my code is wrong, I translated from this source:
https://github.com/dansanderson/lexaloffle/blob/main/pxa_compress_snippets.c
the decompress-code to lua, so it is possible that I made a mistake.
I can't find a erro, so I looked at the rom-data:
4300 00 70 78 61 03 BC 02 39 02 40 C1 AC CE 6D 8C 2E .pxa.¼.9.@Á¬ÎmŒ. |
the first 8 bytes (00 70 78 61 03 BC 02 39) are the header, so the first databyte is 02
or binary: 00000010
When I look in decompress code:
while (src_pos < comp_len && dest_pos < raw_len && dest_pos < max_len) { int block_type = getbit(); // printf("%d %d\n", src_pos, block_type); fflush(stdout); if (block_type == 0) { // block int block_offset = getnum() + 1; int block_len = getchain(BLOCK_LEN_CHAIN_BITS, 100000) + PXA_MIN_BLOCK_LEN; // copy // don't just memcpy because might be copying self for repeating pattern while (block_len > 0){ out_p[dest_pos] = out_p[dest_pos - block_offset]; dest_pos++; block_len--; } |




A little demo of importing dithered pictures. The rom contain 3 pictures, switch with x/o.
Images are created with jaP8e
https://www.lexaloffle.com/bbs/?tid=49307



Features
- Source code in lua!
- Editor for sprite, map, sound, music, charset
- Map editor with support of custom width / size
- Name sound and music
- Custom palette with the extended 128+ color-ids (32 Colors in total)
- Charset editor with possible to export single characters and variable width
- Hex editor to copy & past memory to pico-8 string (URL raw memory access format )
- Modular design
- Import images as sprite sheet, map(!), label - with optional dithering
IMPORTANT
This is a beta release! This means, there are bugs, the program can crash. Make backups before using the editor.
Download
https://github.com/GPIforGit/jaP8e/releases
basic control/setup
Set the path to pico-8.exe
jaP8e needs to know where the pico-8 execute is. Choose in the Menu the "Pico-8" > "Set Pico8 exectuable" option to set the path. Otherwise it can't run any code or playback sound.
Pico-8 Remote
Since I don't know how to program sounds like in pico-8, jaP8e can't playback sound by default. But it is possible to start a "Remote"-pico-8, which runs in the background and is controlled by jaP8e. Activate this option in the "Pico-8"-menu. After this you can playback any sound effect and music during jaP8e.
This function starts a pico-8 with the remote.p8 file in the background. I send commands through stdin/stdout to this remote.
Change Values in the grey input boxes
You can change the values of the grey input boxes by left click in it and use the keyboard. Alternative you can press and hold the right mousebutton and change the value with x-mouse-movement. The third possibility is to use the mouse wheel over the input fields.
basic layout
On the top you find the modules-tab to switch the editors. On the right top side are currently open files. A Star in the file name indicates that the file has unchanged data.
memory layout
jaP8e "simulate" the memory of pico-8, with a rom and ram section. The rom-section is stored normaly like pico8 does and can access normaly. RAM is stored as meta-data and can't access directly in pico-8, but you can export ram as string to copy in the source code (HEX-Editor).
Also you can reposition the map, sprite, sound, music, spriteflags to any memory location, even when pico 8 doesn't support it.
For example, when you don't use a map in your pico-8-project, you can store there additional sprite data. Simple reposition the sprite to 0x1000 to draw in the map-data. In pico-8 you must manually copy the memory (memcpy) to access this additional sprite data.
Error-message and disable a module
When a error happen, a message box with ok and cancel will open. With ok jaP8e will ignore the error. With cancel the module which cause the error will disabled. At least you can try to save your work when a error happen.
Source Editor










I think, that it is common to print a text in center of the screen.
With the variable font it become a little bit complicated..
When the text is variable we must do something like this.
str = "text" len = print(str,0,-0x4000) -- print outside to get the length print(str, 64-len\2, 128) |
it would be nice, when instead of the x-coordinate a string with the position could be added
str = "text" print(str, "center", 128) |
possible "key-words" would be: "left", "center", "right"
for y would be "top", "center", "bottom"
btw. a "printsize" function would be nice, don't draw anything, only return width and height in pixels.


Recreation of a C64 classic: Castles of Dr. Creep.
Compared to the original there are some changes, on the one hand because the layout is different (40x24 vs 16x16), on the other hand because I have defused some "backtracking" and death traps. Nevertheless, please note, the levels are from 1984 - there you have something different design.
Story






I have translated and extend the lua code from here
https://rosettacode.org/wiki/LZW_compression
I tried to reduce the token count, but I wouldn't surprised when someone will shrink it more.
lzw is the codec that for example gif use, it was patented, but it expired 2004.
more information:
https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch
I tested the code with the JELPI-Graphic&Sound data - and it will compress it to 6094 Bytes (from 17152 - ~36%).
With the next update the high-memory above 0x8000 will be useable (at the moment only with a undocumented poke), my plan is to place there 32kbit of graphic and sound data. The problem is, that this memory is not saved and I don't want to store it in the source-code because it is too big.


it would be nice, when the poke() would return the address after the poke, like print() does.
for example:
adr=poke(adr,1) |
should do the same as
poke(adr,1) adr+=1 |
or
adr=poke2(adr,0xffff) |
instead of
poke2(adr,0xffff) adr+=2 |
or
str="abcdef" adr = poke(adr,ord(str,1,#str)) |
instead
str="abcdef" poke(adr,ord(str,1,#str)) adr+=#str |


it would be nice to select where the pause menu should appear. Also the possiblity to draw a custom background for the pause.
For example for a RPG. It would be useful to draw the player-status on screen and the pause-menu on the right button of the screen. In combination with the menuitem-command it would be an easy and "cheap" possibility to create a status-menu. Or display a map of the current level, an inventory and so on.
Suggestion:
menustyle([<position>[,<draw-function>]])
position could be 0=top left, 1=top, 2 top right, 3 left, 4 center (default), 5 right, 6 bottom left, 7 bottom, 8 bottem right
And draw-function is a function which is called direct before the pause-menu appears.


When you want to use the shared part of the worldmap, you can only definied 127 Sprites. In Map-Editor the high-bit 0x80 is completly unused.
It would be nice to set a "Map mode" to use this "wasted" bit. Possible solutions would be one of this
- Flip X
- Flip Y
- Use second palette / apply fill pattern
With Flip you can simple reduce the needed sprites with flipping:
![]() |
[16x16] |
Also second palette you can reuse sprites like here (cloud/bush)
![]() |
[24x16] |

