colors
PICO-8 has 16 default colors (0-15) and another 16 hidden colors (128 to 143) but these are not easy to access.
Default Palette
Number | Hex Color | Name * |
---|---|---|
00 |
#000000 | black |
01 |
#1D2B53 | dark blue |
02 |
#7E2553 | dark purple |
03 |
#008751 | dark green |
04 |
#AB5236 | brown |
05 |
#5F574F | dark gray |
06 |
#C2C3C7 | light gray |
07 |
#FFF1E8 | white |
08 |
#FF004D | red |
09 |
#FFA300 | orange |
10 |
#FFFF27 | yellow |
11 |
#00E756 | green |
12 |
#29ADFF | blue |
13 |
#83769C | indigo |
14 |
#FF77A8 | pink |
15 |
#FFCCAA | peach |
* official names in manual
Hidden Palette
Number | Hex color | Name * |
---|---|---|
128 / -16 |
#291814 | onyx |
129 / -15 |
#111D35 | midnight |
130 / -14 |
#422136 | plum |
131 / -13 |
#125359 | forest |
132 / -12 |
#742F29 | chocolate |
133 / -11 |
#49333B | eggplant |
134 / -10 |
#A28879 | beige |
135 / -9 |
#F3EF7D | lemon |
136 / -8 |
#BE1250 | burgundy |
137 / -7 |
#FF6C24 | pumpkin |
138 / -6 |
#A8E72E | lime |
139 / -5 |
#00B543 | jade |
140 / -4 |
#065AB5 | royal |
141 / -3 |
#754665 | mauve |
142 / -2 |
#FF6E59 | coral |
143 / -1 |
#FF9D81 | salmon |
* unofficial names
Analysis of the Default Palette
If we take the full rainbow spectrum, which you might be familiar with when selecting a color in an image editing tool, and we shift all the many colors towards their closest PICO-8 equivalent, then we get this PICO-8 Palette Spectrum.
You can use this to study the palette. For example, if you choose a spot and move along vertically, you'll see many possible combinations of light and dark tones for shading and transitions. If you move horizontally, you will see which colors sit at around the same saturation level. High saturation colors (towards the top) are good for standing out in the foreground against low saturation colors (towards the bottom) in the background.
Another way to display and study this spectrum is as concentric circles, where the innermost center is white and the outermost shell is black. This can help you see gradients of light to dark by moving outward in different directions similar to moving down the above image. This also better visualizes the endless continuation around the spectrum if you move along the circle in a clockwise or counterclockwise direction, which can be helpful to build colorful shifting animations that loop through the colors more seamlessly.
Color Ramps of the Default Palette
Here are some examples of color ramps generated from studying these spectrums to create smooth shading combinations that you can use to improve your pixel art in PICO-8.
References for Mixed Palettes
Here are some helpful reference images you can use while drawing PICO-8 sprites, or choosing the custom palette for your game. You can swap out these colors anytime, with some limitations. It is more common however to set your own custom palette by selecting 16 colors from these 32 options.
This is how the hidden palette lines up with the default palette, showing beautiful darker options to the originals. Also notice that this refers to the hidden palette as negative numbers. This is another, possibly easier, way to access them.
Here are some color ramps using a mix of both palettes, useful if you want to make an original gameboy looking game, or a grayscale game, or simply include more shades of an important color in your game.
This is another configuration of the two palettes merged together with the default palette on the outside and the hidden or secret palette on the inside.
5368
4 Jun 2024
color
color(number)
This will set the color to be used in the next draw call, such as: print() circ() rect() line() oval()
If those draw functions do not use the optional color setting, then whatever color was last set will be used. By using the optional color settings in functions that have them, it sets that color to be the currently selected color.
Example:
color(8) --set color to red
print("hello world")
The above is the same as:
print("hello world",0,0,8)
print("hello",0,0,8) --red
oval(30,2,50,12)
color(7) --white
print("world")
rect(60,2,80,12)
Notice that the oval is red even though we don't tell it to be nor did we use color(8)
. This happened because setting the color to red in print actually sets the draw color the same way as using color()
would. Then we do use color(7)
to change the draw color to white, and this applies the color to the next print and rectangle draws.
1345
19 Mar 2023
pal
pal
= "palette" (set of colors)
pal( color1, color2, [palette] )
color1 | color number to change from |
color2 | new color number to change to |
palette | (optional) set the type of palette change. Default = 0. See Palette Types below |
pal() --reset
Calling pal
with empty parentheses resets all colors to the default palette (including transparency settings):
Palette Types
0 = Draw Palette
Setting it to Draw Palette (using 0 or leaving it empty) will change the color palette for all future draws. Does not affect anything that was already drawn.
spr(1,10,10) --draw red flower
pal(8,12,0) --change reds to blue
spr(1,20,10) --draw same flower
In the above code, we set color #8 (red) to be color #12 (blue), so when we draw the next same exact sprite, it will draw as blue instead, but does not affect the first flower.
Even though we often refer to this function as "Palette Swap", note that it does not actually "swap" the colors around. Instead, it only replaces the first color with the second, while the second color remains the same.
1 = Display Palette
Setting it to Display Palette (using 1) re-draws the whole screen before it gets displayed at the end of each frame. This will affect everything already drawn to the screen.
function _draw()
cls()
spr(1,10,10) --draw red flower
pal(8,12,1) --change reds to blue
spr(1,20,10) --draw same flower
end
We can do the same demonstration as above, using a red flower sprite in sprite #1. However, the palette changes will reset when you exit the game. So we need to put this code inside of the _draw()
function to stay in the game and view the changes. Press ESC and you will see the sprites turn back to the color red when the Display Palette gets reset.
Note that this also affects the editor colors. For example, if you type PAL(8,12,1)
into the command line and press enter, all of the red (#8) immediately changes to blue (#12) even though it has already been drawn.
You can poke memory 0x5f2e
and set it to 1 to force the palette to keep your changes so that both your game and the editors will maintain your palette changes.
poke( 0x5f2e, 1 )
2 = Secondary Palette
From the manual: "Used by FILLP() for drawing sprites. This provides a mapping from a single 4-bit colour index to two 4-bit colour indexes."
(to be expanded)
Reset Palette Type
pal(#) --pallete type to default
Calling pal
with a single number (#0-2) will treat that as the palette type to reset to the default palette (including transparency settings).
Rearrange the Palette
pal( table, [palette] )
Instead of the 2 color number arguments, it is also possible to pass a single table. This sets the full palette using a table of color numbers in order that they are arranged.
pal({15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0})
This will swap color numbers 1-15 (in order) to the numbers set within the table (reverse order).
However, notice that color #0 did not change. That's because Lua tables start at 1 so the first number in the table will be set to color #1, and the next one #2, and so on, until #15. The 16th color in the table will be set to #0.
If you would prefer the order of your table to start at #0, then you can force the table index number like this:
pal( { [0]=15, 14, 13, 12, 11, ... } )
1695
10 Mar 2023
palt
palt
= "palette transparency"
palt( color, boolean )
color | a color number |
boolean | true or false to set transparency on or off |
Example:
spr(1,10,10) --draw red flower palt(8,true) --red transparent spr(1,20,10) --draw same flower
As you can see, this code first drew a red flower, but before it drew the second flower, the color red was set to be transparent so the red petals don't appear on the second flower after the call to palt
.
Reset Transparency
palt()
Calling palt
with empty parentheses resets all colors to default transparency, where only black (#0) is transparent.
1262
9 Mar 2023
PICO-8 has 16 extra colors that are undocumented and a bit tricky to access.
This means we actually have 32 colors to choose from and you can set your own 16 color palette using a mix of them both.
Using the palette swapping function, you can change a default color with a hidden color but you must set the last argument to 1.
pal( current color, new color, 1 )
You also need to use poke
to access the PICO-8 memory and set the color palette to change. Do this once somewhere before using pal
to set a custom palette.
poke( 0x5f2e, 1 )
Swap the full palette using a mix of default and hidden color numbers in a table of 16 color numbers and the second argument set to 1.
pal( {1,2,3...} ,1 )
Swap all of the default colors to the hidden colors.
pal( {[0]=128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143}, 1 )
Warning:
If you swap specific colors of your custom palette or change the transparent color, you can do that without any problems. However you will likely want to reset the palette back to normal after that. Normally you just call pal()
to reset it but this will completely reset your custom palette back to the default colors. So when resetting your custom palette, you must call the entire pal( custom_palette_table, 1 )
to set your custom colors every time. So it is common to create your own reset_pal()
function like this:
function _init()
poke( 0x5f2e, 1 ) --enable hidden colors
custom_palette = {[0]=0,128,133,5,6,7,1,140,12,3,139,11,130,132,4,15}
reset_pal()
end
function reset_pal()
pal()
pal( custom_palette, 1 )
end
3613
24 May 2024