Skip to main content
Palettes are collections of colors used in your sprite. While all sprites have palettes, they are especially important for Indexed color mode, where pixels store palette indices instead of actual colors.

What are Palettes?

A palette is an ordered collection of colors (up to 256) that defines the available colors for your artwork. In Indexed mode, each pixel references a palette entry rather than storing color data directly.
Even RGB sprites have palettes - they’re used by color quantization algorithms and as a color reference for artists.

Creating Palettes

Default Palettes

-- New sprites start with a 256-color black palette
local sprite = Sprite(32, 32, ColorMode.INDEXED)
local palette = sprite.palettes[1]
print(#palette)  -- 256

-- All colors are black by default
for i = 0, #palette - 1 do
  print(palette:getColor(i))  -- Color(0, 0, 0)
end

Creating Custom Palettes

-- Create palette with specific size
local palette = Palette(16)  -- 16-color palette
print(#palette)  -- 16

-- Set colors
palette:setColor(0, Color(0, 0, 0))       -- Black
palette:setColor(1, Color(255, 255, 255)) -- White
palette:setColor(2, Color(255, 0, 0))     -- Red
palette:setColor(3, Color(0, 255, 0))     -- Green
palette:setColor(4, Color(0, 0, 255))     -- Blue

Working with Palette Colors

Getting and Setting Colors

local sprite = Sprite(32, 32, ColorMode.INDEXED)
local palette = sprite.palettes[1]

-- Resize palette
palette:resize(8)  -- Now 8 colors
print(#palette)    -- 8

-- Set colors by index (0-based)
palette:setColor(0, Color(255, 0, 0))    -- Index 0: Red
palette:setColor(1, Color(0, 255, 0))    -- Index 1: Green  
palette:setColor(2, Color(0, 0, 255))    -- Index 2: Blue
palette:setColor(3, Color(255, 255, 0))  -- Index 3: Yellow

-- Get colors
local red = palette:getColor(0)
print(red.red, red.green, red.blue)  -- 255, 0, 0

-- Alternative syntax
local green = palette:entry(1)

Colors with Alpha

local palette = Palette(4)

-- Set color with alpha channel
local semiTransparent = Color{red=100, green=50, blue=10, alpha=128}
palette:setColor(3, semiTransparent)

print(palette:getColor(3).alpha)  -- 128

-- Check if palette uses alpha
if palette:hasAlpha() then
  print("Palette has colors with alpha < 255")
end

if palette:hasSemiAlpha() then
  print("Palette has colors with 0 < alpha < 255")
end

Palette Properties

Palette Metadata

local palette = Palette{ fromFile = "mypalette.gpl" }

-- Filename
print(palette.filename)  -- "mypalette.gpl"
palette:setFilename("newname.gpl")

-- Comment (from .gpl files)
print(palette.comment)  -- Author, description, etc.
palette:setComment("Custom palette for game")

-- Frame association
print(palette.frame)  -- Frame where palette changes
palette:setFrame(5)   -- Associate with frame 5

Entry Names

You can name individual palette entries:
local palette = Palette(8)

-- Set entry names
palette:setEntryName(0, "Background")
palette:setEntryName(1, "Shadow")
palette:setEntryName(2, "Skin")
palette:setEntryName(3, "Highlight")

-- Get entry names  
print(palette:getEntryName(0))  -- "Background"

Sprite Palettes

Multiple Palettes Per Sprite

Sprites can have different palettes at different frames:
local sprite = Sprite(32, 32, ColorMode.INDEXED)

-- Initial palette
local pal1 = Palette(4)
pal1:setColor(0, Color(0, 0, 0))       -- Black
pal1:setColor(1, Color(255, 0, 0))     -- Red
pal1:setColor(2, Color(0, 255, 0))     -- Green
pal1:setColor(3, Color(0, 0, 255))     -- Blue
sprite:setPalette(pal1)

-- Check all palettes
print(#sprite.palettes)  -- 1

-- Set different palette for later frame
local pal2 = Palette(4)
pal2:setColor(0, Color(0, 0, 0))       -- Black
pal2:setColor(1, Color(255, 128, 0))   -- Orange
pal2:setColor(2, Color(255, 255, 0))   -- Yellow  
pal2:setColor(3, Color(128, 0, 255))   -- Purple
pal2:setFrame(5)
sprite:setPalette(pal2)

print(#sprite.palettes)  -- 2 (one for frames 1-4, one for 5+)

Getting Frame-Specific Palette

local sprite = Sprite(32, 32, ColorMode.INDEXED)

-- Get palette for specific frame
local framePalette = sprite:palette(1)  -- Palette at frame 1
print(#framePalette)

-- Palettes can change between frames
local palette5 = sprite:palette(5)   -- May be different

Managing Sprite Palettes

local sprite = Sprite(32, 32, ColorMode.INDEXED)

-- Get all palettes
local palettes = sprite:getPalettes()
for i, pal in ipairs(palettes) do
  print("Palette", i, "has", #pal, "colors")
end

-- Reset to single palette
sprite:resetPalettes()  -- Removes all but first palette
print(#sprite.palettes)  -- 1

-- Delete specific palette
sprite:deletePalette(5)  -- Remove palette starting at frame 5

Palette Operations

Copying Palettes

-- Copy palette
local original = Palette(8)
local copy = Palette(original)

-- Copy colors to another palette
local source = Palette(16)
local dest = Palette(16)
source:copyColorsTo(dest)

Comparing Palettes

local pal1 = Palette(4)
local pal2 = Palette(4)

-- Set same colors
for i = 0, 3 do
  pal1:setColor(i, Color(i * 64, 0, 0))
  pal2:setColor(i, Color(i * 64, 0, 0))
end

-- Compare palettes
if pal1 == pal2 then
  print("Palettes are identical")
end

if pal1 ~= pal2 then
  print("Palettes differ")
end

-- Count differences
local from, to = 0, 0
local diffCount = pal1:countDiff(pal2, from, to)
print("Different colors:", diffCount)

Grayscale Palette

-- Create grayscale palette
local grayscale = Palette:createGrayscale()
print(#grayscale)  -- 256 colors from black to white

-- Check if palette is completely black
local palette = Palette(16)
if palette:isBlack() then
  print("All colors are black")
end

-- Make palette black
palette:makeBlack()

Color Finding and Matching

Find Exact Colors

local palette = Palette(16)
palette:setColor(0, Color(255, 0, 0))   -- Red at index 0
palette:setColor(1, Color(0, 255, 0))   -- Green at index 1
palette:setColor(2, Color(0, 0, 255))   -- Blue at index 2

-- Find exact match
local index = palette:findExactMatch(255, 0, 0, 255, -1)
print(index)  -- 0 (red is at index 0)

-- Check if color exists
local exists = palette:findExactMatch(Color(0, 255, 0))
print(exists)  -- true (green exists)

Find Best Fit Colors

local palette = Palette(4)
palette:setColor(0, Color(0, 0, 0))       -- Black
palette:setColor(1, Color(255, 0, 0))     -- Red
palette:setColor(2, Color(0, 255, 0))     -- Green
palette:setColor(3, Color(0, 0, 255))     -- Blue

-- Find closest color (for color not in palette)
local index = palette:findBestfit(200, 50, 50, 255, -1)
print(index)  -- Returns index of closest color (probably red)

Find Mask Color

local palette = Palette(8)

-- Find suitable transparent/mask color
local maskIndex = palette:findMaskColor()
print("Suggested mask color index:", maskIndex)

Palette Gradients

local palette = Palette(32)

-- Set start and end colors
palette:setColor(0, Color(255, 0, 0))   -- Red
palette:setColor(31, Color(0, 0, 255))  -- Blue

-- Create gradient between them
palette:makeGradient(0, 31)  -- RGB gradient

-- Create hue-based gradient
palette:makeHueGradient(0, 31)  -- Hue shift gradient

Adding Colors to Palette

local palette = Palette(4)

-- Resize palette
palette:resize(8)  -- Now has 8 slots

-- Add individual color
palette:addEntry(Color(255, 128, 0))  -- Adds at end
print(#palette)  -- 9

-- Add non-repeated colors from another palette
local source = Palette(16)
-- ... set colors in source ...
palette:addNonRepeatedColors(source)  -- Adds unique colors only

Palette Remapping

Change how indices map to colors:
local sprite = Sprite(32, 32, ColorMode.INDEXED)
local palette = sprite.palettes[1]
local remap = { [0]=1, [1]=0, [2]=3, [3]=2 }  -- Swap indices

-- Apply remap to palette
palette:applyRemap(remap)

-- This swaps the colors at the indices

Default Palette

Aseprite has a default palette for new sprites:
-- Get default palette
local defaultPal = app.defaultPalette
print(#defaultPal)  -- Usually DB32 (32 colors)

-- Set new default
local db16 = Palette{ fromResource = "DB16" }
app.defaultPalette = db16

-- New sprites will use DB16 palette

Saving and Loading Palettes

-- Save palette to file
local palette = Palette(16)
-- ... set colors ...
palette:saveAs("mypalette.gpl")  -- GIMP palette format
palette:saveAs("mypalette.pal")  -- Other palette formats

-- Load palette
local loaded = Palette{ fromFile = "mypalette.gpl" }

-- Apply to sprite  
sprite:setPalette(loaded)

Best Practices

For Indexed mode projects, design your palette before drawing:
  1. Research your target system’s limitations
  2. Choose base colors carefully
  3. Include ramps for shading
  4. Reserve index 0 for transparency (common convention)
Group related colors together:
-- Indices 0-3: Transparency and black ramp
palette:setColor(0, Color(0, 0, 0, 0))   -- Transparent
palette:setColor(1, Color(32, 32, 32))   -- Dark shadow
palette:setColor(2, Color(64, 64, 64))   -- Shadow
palette:setColor(3, Color(96, 96, 96))   -- Light shadow

-- Indices 4-7: Red ramp
palette:setColor(4, Color(128, 0, 0))    -- Dark red
palette:setColor(5, Color(192, 0, 0))    -- Medium red
palette:setColor(6, Color(255, 64, 64))  -- Red
palette:setColor(7, Color(255, 128, 128))-- Light red
Name important palette entries for easier reference:
palette:setEntryName(0, "Transparent")
palette:setEntryName(1, "Outline")
palette:setEntryName(4, "Skin-Shadow")
palette:setEntryName(5, "Skin-Base")  
palette:setEntryName(6, "Skin-Highlight")
Keep your palettes as separate .gpl or .pal files so you can:
  • Reuse them across projects
  • Share them with team members
  • Version control them separately
  • Apply them to new sprites easily

Common Palette Sizes

SystemColorsNotes
NES54 total4 colors per sprite palette
Game Boy4Black, dark gray, light gray, white
SEGA Genesis512 total16 colors per palette, 4 palettes
GBA32,768 total256 colors per palette
DB1616Popular indie palette
DB3232Extended indie palette
Pico-816Fixed palette

Color Modes

Learn about Indexed color mode

Sprites

Understand sprite creation

API Reference

For complete API documentation, see:

Build docs developers (and LLMs) love